基础

1.Kubernetes是什么,优点有哪些

Kubernetes是自动化容器操作的开源平台。这些容器操作包括:部署,调度和节点集群间扩展。更高了看,是基于容器技术的分布式架构方案,是一个完备的分布式系统支撑平台。

  • 方便开发复杂系统,可以把更多精力放在业务开发上。
  • 全面拥抱微服务架构。
  • 随时随地可以把系统整体搬迁到公有云。
  • 弹性扩容机制可以让我应对突发流量,在公有云上接借用务,减少公司硬件投入。
  • 横向扩容能力很强,添加Node就可以。

2.基本组成部分

Master节点主要有五个组件,分别是kubectl、api-server、controller-manager、kube-scheduler 和 etcd。
node节点主要有三个组件,分别是 kubelet、kube-proxy 和 容器运行时 docker 或者 rkt。

  • kubectl:客户端命令行工具,作为整个系统的操作入口。
  • apiserver:以REST API服务形式提供接口,作为整个系统的控制入口。
  • controller-manager:执行整个系统的后台任务,包括节点状态状况、Pod个数、Pods和Service的关联等。
  • kube-scheduler:负责节点资源管理,接收来自kube-apiserver创建Pods任务,并分配到某个节点。
  • etcd:负责节点间的服务发现和配置共享。
  • kube-proxy:运行在每个计算节点上,负责Pod网络代理。定时从etcd获取到service信息来做相应的策略。
  • kubelet:运行在每个计算节点上,作为agent,接收分配该节点的Pods任务及管理容器,周期性获取容器状态,反馈给kube-apiserver。
  • DNS:一个可选的DNS服务,用于为每个Service对象创建DNS记录,这样所有的Pod就可以通过DNS访问服务了。

3.Kubernetes与Docker Swarm的区别

特点KubernetesDocker
安装复杂简单
集群强大
GUI有Dashboard没有
扩容能力高可扩容性,扩容快速同样高可扩容,而且扩容速度更快
自动扩容可以不可以
负载均衡不同Pod之间的负载均需要手动配置可以进行自动的负载均衡
滚动更新和回滚可以滚动更新和自动回滚可以滚动更新,不能自动回滚
数据卷只有同一个Pod中的容器可以共享卷所有容器都可以共享卷

4.K8s中镜像的下载策略是什么?

可通过命令“kubectl explain pod.spec.containers”来查看imagePullPolicy这行的解释。

K8s的镜像下载策略有三种:Always、Never、IFNotPresent;

  • Always:镜像标签为latest时,总是从指定的仓库中获取镜像;

  • Never:禁止从仓库中下载镜像,也就是说只能使用本地镜像;

  • IfNotPresent:仅当本地没有对应镜像时,才从目标仓库中下载。

默认的镜像下载策略是:当镜像标签是latest时,默认策略是Always;当镜像标签是自定义时(也就是标签不是latest),那么默认策略是IfNotPresent。

5.标签与标签选择器的作用是什么?

标签:是当相同类型的资源对象越来越多的时候,为了更好的管理,可以按照标签将其分为一个组,为的是提升资源对象的管理效率。
标签选择器:就是标签的查询过滤条件。目前API支持两种标签选择器:

  • 基于等值关系的,如:“=”、“”“”、“!=”(注:“”也是等于的意思,yaml文件中的matchLabels字段);
  • 基于集合的,如:in、notin、exists(yaml文件中的matchExpressions字段)。

集群

1.Kubernetes的负载均衡器

负载均衡器是暴露服务的最常见和标准方式之一。根据工作环境使用两种类型的负载均衡器,即内部负载均衡器或外部负载均衡器。内部负载均衡器自动平衡负载并使用所需配置分配容器,而外部负载均衡器将流量从外部负载引导至后端容器。

2.kubelet 监控 Node 节点资源使用是通过什么组件来实现的

kubernetes早期采用heapster来实现完整的性能数据采集和监控,然后用Metrics Server替换了前者,用于提供核心指标,包括Node、Pod的CPU和内存的使用。而Metrics Server需要采集node上的cAdvisor提供的数据资源。

开源软件 cAdvisor 是用于监控容器运行状态的利器之一,在 Kubernetes 系统中,cAdvisor 已被默认集成到 kubelet 组件内,当 kubelet 服务启动时,它会自动启动 cAdvisor 服务,然后 cAdvisor 会实时采集所在节点的性能指标及在节点上运行的容器的性能指标。kubelet 的启动参数 --cadvisor-port 可自定义 cAdvisor 对外提供服务的端口号,默认是 4194。
在这里插入图片描述
前端可以用Grafana实现自定义的UI监控界面。

资源对象

1.Pod的状态

  • Pending
    已经创建了Pod,但是其内部还有容器没有创建。
  • Running
    Pod内部的所有容器都已经创建,只有由一个容器还处于运行状态或者重启状态。
  • Succeeed
    Pod内所有容器均已经成功执行并且退出,不会再重启。
  • Failed
    Pod内所有容器都退出,但至少有一个为退出失败状态。
  • Unknown
    由于某种原因不能获取该Pod的状态,可能是网络问题。

2.deployment/rs的区别

deployment是rs的超集,提供更多的部署功能,如:回滚、暂停和重启、 版本记录、事件和状态查看、滚动升级和替换升级。

如果能使用deployment,则不应再使用rc和rs。

3.rc/rs实现原理

问题:rc/rs功能是怎么实现的。详述从API接收到一个创建rc/rs的请求,到最终在节点上创建pod的全过程,尽可能详细。另外,当一个pod失效时,kubernetes是如何发现并重启另一个pod的?

Replication Controller 可以保证Pod始终处于规定的副本数。

而当前推荐的做法是使用Deployment+ReplicaSet。

ReplicaSet 号称下一代的 Replication Controller,当前唯一区别是RS支持set-based selector。

RC是通过ReplicationManager监控RC和RC内Pod的状态,从而增删Pod,以实现维持特定副本数的功能。

RS也是大致相同。

4.k8s 创建一个pod的详细流程,涉及的组件怎么通信的

  1. 客户端提交创建请求,可以通过 api-server 提供的 restful 接口,或者是通过 kubectl 命令行工具,支持的数据类型包括 JSON 和 YAML。
  2. api-server 处理用户请求,将 pod 信息存储至 etcd 中。
  3. kube-scheduler 通过 api-server 提供的接口监控到未绑定的 pod,尝试为 pod 分配 node 节点,主要分为两个阶段,预选阶段和优选阶段,其中预选阶段是遍历所有的 node 节点,根据策略筛选出候选节点,而优选阶段是在第一步的基础上,为每一个候选节点进行打分,分数最高者胜出。
  4. 选择分数最高的节点,进行 pod binding 操作,并将结果存储至 etcd 中。
  5. 随后目标节点的 kubelet 进程通过 api-server 提供的接口监测到 kube-scheduler 产生的 pod 绑定事件,然后从 etcd 获取 pod 清单,下载镜像并启动容器。

5.kubenetes针对pod资源对象的健康监测机制

K8s中对于pod资源对象的健康状态检测,提供了三类probe(探针)来执行对pod的健康监测:

  • livenessProbe探针
    可以根据用户自定义规则来判定pod是否健康,用于判断容器是否处于Running状态,如果不是,kubelet就会杀掉该容器,并根据重启策略做相应的处理。如果容器不包含该探针,那么kubelet就会默认返回值都是success。

  • ReadinessProbe探针
    同样是可以根据用户自定义规则来判断pod是否健康,容器服务是否可用(Ready),如果探测失败,控制器会将此pod从对应service的endpoint列表中移除,从此不再将任何请求调度到此Pod上,直到下次探测成功。

  • startupProbe探针
    启动检查机制,应用一些启动缓慢的业务,避免业务长时间启动而被上面两类探针kill掉,这个问题也可以换另一种方式解决,就是定义上面两类探针机制时,初始化时间定义的长一些即可。

每种探测方法能支持以下几个相同的检查参数,用于设置控制检查时间:

  • initialDelaySeconds:初始第一次探测间隔,用于应用启动的时间,防止应用还没启动而健康检查失败;
  • periodSeconds:检查间隔,多久执行probe检查,默认为10s;
  • timeoutSeconds:检查超时时长,探测应用timeout后为失败;
  • successThreshold:成功探测阈值,表示探测多少次为健康正常,默认探测1次。

6.pod的重启策略是什么?

通过命令“kubectl explain pod.spec”查看pod的重启策略。(restartPolicy字段)

  • Always:但凡pod对象终止就重启,此为默认策略。
  • OnFailure:仅在pod对象出现错误时才重启。

7.DaemonSet资源对象的特性?

DaemonSet这种资源对象会在每个k8s集群中的节点上运行,并且每个节点只能运行一个pod,这是它和deployment资源对象的最大也是唯一的区别。所以,在其yaml文件中,不支持定义replicas,除此之外,与Deployment、RS等资源对象的写法相同。

它的一般使用场景如下:

  • 在去做每个节点的日志收集工作;
  • 监控每个节点的的运行状态。

8.删除一个Pod会发生什么事情?

Kube-apiserver会接受到用户的删除指令,默认有30秒时间等待优雅退出,超过30秒会被标记为死亡状态,此时Pod的状态Terminating,kubelet看到pod标记为Terminating就开始了关闭Pod的工作。

关闭流程如下:
1、 pod从service的endpoint列表中被移除;
2、 如果该pod定义了一个停止前的钩子,其会在pod内部被调用,停止钩子一般定义了如何优雅的结束进程;
3、 进程被发送TERM信号(kill -14)
4、 当超过优雅退出的时间后,Pod中的所有进程都会被发送SIGKILL信号(kill -9)。

网络

1.详述kube-proxy原理

问题:详述kube-proxy原理,一个请求是如何经过层层转发落到某个pod上的整个过程。请求可能来自pod也可能来自外部。

集群中每个Node上都会运行一个kube-proxy服务进程,他是Service的透明代理兼均衡负载器,其核心功能是将某个Service的访问转发到后端的多个Pod上。kube-proxy通过监听集群状态变更,并对本机iptables做修改,从而实现网络路由。 而其中的负载均衡,也是通过iptables的特性实现的。

另外我们需要了解k8s中的网络配置类型,有如下几种:

  • hostNetwork Pod使用宿主机上的网络,此时可能端口冲突。
  • hostPort 宿主机上的端口与Pod的目标端口映射。
  • NodePort 通过Service访问Pod,并给Service分配一个ClusterIP。

从kubernetes1.8开始,词用了IPVS(IP Virtual Server)模式,用于路由规则的配置。相比iptables,IPVS具有如下优势:

  • 为大型集群提供了更好的扩展性和性能。采用哈希表的数据结构,更高效。
  • 支持更复杂的负载均衡算法。
  • 支持服务器健康检查和连接重试。
  • 可以动态修改ipset的集合。

2.flannel 和 ovs 网络的区别

(1)配置是否自动化

OpenvSwitch作为开源的交换机软件,相对比较成熟和稳定,支持各种网络隧道和协议,经历了大型项目 OpenStack 的考验,而 flannel 除了支持建立覆盖网络来实现 Pod 到 Pod 之间的无缝通信之外,还跟 docker、k8s 的架构体系紧密结合,flannel 能感知 k8s 中的 service 对象,然后动态维护自己的路由表,并通过 etcd 来协助 docker 对整个 k8s 集群的 docker0 网段进行规范,而 ovs ,这些操作则需要手动完成,假如集群中有 N 个节点,则需要建立 N(N-1)/2 个 Vxlan 或者 gre 连接,这取决于集群的规模,如果集群的规模很大,则必须通过自动化脚本来初始化,避免出错。

(2)是否支持隔离

flannel 虽然很方便实现 Pod 到 Pod 之间的通信,但不能实现多租户隔离,也不能很好地限制 Pod 的网络流量,而 ovs 网络有两种模式:单租户模式和多租户模式,单租户模式直接使用 openvswitch + vxlan 将 k8s 的 pod 网络组成一个大二层,所有的 pod 可以互相通信访问,多租户模式以 Namespace 为维度分配虚拟网络,从而形成一个网络独立用户,一个 Namespace 中的 pod 无法访问其他 Namespace 中的 pod 和 svc 对象。

参考博客

3.k8s集群外流量怎么访问Pod?

可以通过Service的NodePort方式访问,会在所有节点监听同一个端口,比如:30000,访问节点的流量会被重定向到对应的Service上面。

服务

1.K8S 资源限制 QoS

Quality of Service,Qos 主要有三种类别:

  • BestEffort
    什么都不设置(CPU or Memory),佛系申请资源。

  • Burstable
    Pod 中的容器至少一个设置了CPU 或者 Memory 的请求

  • Guaranteed
    Pod 中的所有容器必须设置 CPU 和 Memory,并且 request 和 limit 值相等。

2.k8s是怎么进行服务注册的?

Pod启动后会加载当前环境所有Service信息,以便不同Pod根据Service名进行通信。

存储

1.k8s数据持久化的方式有哪些

1.EmptyDir(空目录)
没有指定要挂载宿主机上的某个目录,直接由Pod内保部映射到宿主机上。类似于docker中的manager volume。
主要使用场景:

  • 只需要临时将数据保存在磁盘上,比如在合并/排序算法中;
  • 作为两个容器的共享存储,使得第一个内容管理的容器可以将生成的数据存入其中,同时由同一个webserver容器对外提供这些页面。

emptyDir的特性:
同个pod里面的不同容器,共享同一个持久化目录,当pod节点删除时,volume的数据也会被删除。如果仅仅是容器被销毁,pod还在,则不会影响volume中的数据。
总结来说:emptyDir的数据持久化的生命周期和使用的pod一致。一般是作为临时存储使用。

2.Hostpath
将宿主机上已存在的目录或文件挂载到容器内部。类似于docker中的bind mount挂载方式。
这种数据持久化方式,运用场景不多,因为它增加了pod与节点之间的耦合。
一般对于k8s集群本身的数据持久化和docker本身的数据持久化会使用这种方式,可以自行参考apiService的yaml文件,位于:/etc/kubernetes/main…目录下。

3.PersistentVolume(简称PV)
基于NFS服务的PV,也可以基于GFS的PV。它的作用是统一数据持久化目录,方便管理。
在一个PV的yaml文件中,可以对其配置PV的大小,
指定PV的访问模式:

  • ReadWriteOnce:只能以读写的方式挂载到单个节点;
  • ReadOnlyMany:能以只读的方式挂载到多个节点;
  • ReadWriteMany:能以读写的方式挂载到多个节点。

以及指定pv的回收策略:

  • recycle:清除PV的数据,然后自动回收;
  • Retain:需要手动回收;
  • delete:删除云存储资源,云存储专用;
    #PS:这里的回收策略指的是在PV被删除后,在这个PV下所存储的源文件是否删除)。

若需使用PV,那么还有一个重要的概念:PVC,PVC是向PV申请应用所需的容量大小,K8s集群中可能会有多个PV,PVC和PV若要关联,其定义的访问模式必须一致。定义的storageClassName也必须一致,若群集中存在相同的(名字、访问模式都一致)两个PV,那么PVC会选择向它所需容量接近的PV去申请,或者随机申请。

命令

参考博客

1.查看test这个命名空间下的所有pod,并显示pod的IP地址

kubectl get pods -n test -o wide

2.查看test命名空间下的pod名称为lede的日志,并显示最后30行

kubectl logs lede -n test|tail -n 30

3.查看test的命名空间下pod名称为lede的状态

kubectl describe pods lede -n test

4.如何查看test命名空间下的所有endpoints

kubectl get ep -n test

5. 如何列出所有 namespace 中的所有 pod

kubectl get pods --all-namespaces

6.如何查看test命名空间下的所有ingress

kubectl get ingress -n test

7.如何删除test命名空间下某个deploymemt,名称为ledes

kubectl delete deploy ledes -n test

8.如何缩减test命名空间下deployment名称为gitlab的副本数为1

kubectl scale deployment gitlab -n test --replicas=1

9.如何在不进入pod内查看命名空间为test,pod名称为lede的hosts

kubectl exec -it lede -n test – cat /etc/hosts

10. 如何设置节点test-node-10为不可调度以及如何取消不可调度

kubectl cordon test-node-10     #设置test-node-10为不可调度
kubectl uncordon test-node-10   #取消 

11.版本回滚相关的命令

[root@master httpd-web]# kubectl apply -f httpd2-deploy1.yaml –record
#运行yaml文件,并记录版本信息;
[root@master httpd-web]# kubectl rollout history deployment httpd-devploy1
#查看该deployment的历史版本
[root@master httpd-web]# kubectl rollout undo deployment httpd-devploy1 –to-revision=1
#执行回滚操作,指定回滚到版本1

运维

1 某个pod启动的时候需要用到pod的名称,请问怎么获取pod的名称,简要写出对应的yaml配置(考察是否对k8s的Downward API有所了解)

env:
- name: test
  valueFrom:
    fieldRef:
      fieldPath: metadata.name

2.某个pod需要配置某个内网服务的hosts,比如数据库的host,如:192.168.4.124 db.test.com,请问有什么方法可以解决,简要写出对应的yaml配置或其他解决办法

解决办法:搭建内部的dns,在coredns配置中配置内网dns的IP

要是内部没有dns的话,在yaml文件中配置hostAliases,刑如:

hostAliases:
- ip: "192.168.4.124"
  hostnames:
  - "db.test.com"

3 请用系统镜像为centos:latest制作一个jdk版本为1.8.142的基础镜像,请写出dockerfile(考察dockerfile的编写能力)

FROM centos:latest
ARG JDK_HOME=/root/jdk1.8.0_142
WORKDIR /root
ADD jdk-8u142-linux-x64.tar.gz /root
ENV JAVA_HOME=/root/jdk1.8.0_142
ENV PATH=$PATH:$JAVA_HOME/bin
CMD ["bash"]

4.假如某个pod有多个副本,如何让两个pod分布在不同的node节点上,请简要写出对应的yaml文件(考察是否对pod的亲和性有所了解)

affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - topologyKey: "kubernetes.io/hostname"
      labelSelector:
        matchLabels:
          app: test

5.pod的日志如何收集,简要写出方案(考察是否真正有生产经验,日志收集是必须解决的一个难题)

  • 1 每个app的镜像中都集成日志收集组件 部署方便,kubernetes的yaml文件无须特别配置,可以为每个app自定义日志收集配置 强耦合,不方便应用和日志收集组件升级和维护且会导致镜像过大
  • 2 单独创建一个日志收集组件跟app的容器一起运行在同一个pod中 低耦合,扩展性强,方便维护和升级 需要对kubernetes的yaml文件进行单独配置,略显繁琐
  • 3 将所有的Pod的日志都挂载到宿主机上,每台主机上单独起一个日志收集Pod 完全解耦,性能最高,管理起来最方便 需要统一日志收集规则,目录和输出方式
    每个公司的都不一样,下面三个链接可当做参考
    参考
    参考
    参考

6.k8s集群监控

7.集群如何预防雪崩,简要写出必要的集群优化措施

1、为每个pod设置资源限制
2、设置Kubelet资源预留

8.集群怎么升级,证书过期怎么解决,简要说出做法

参考 #更新证书

参考 #集群升级

9.etcd如何备份,简要写出命令

参考

export ETCDCTL_API=3
etcdctl --cert=/etc/kubernetes/pki/etcd/server.crt \
        --key=/etc/kubernetes/pki/etcd/server.key \
        --cacert=/etc/kubernetes/pki/etcd/ca.crt \
        snapshot save /data/test-k8s-snapshot.db

10.在以往的k8s运维中遇到过哪些问题,怎么解决的

11.如何控制滚动更新过程

可以通过下面的命令查看到更新时可以控制的参数:

[root@master yaml]# kubectl explain deploy.spec.strategy.rollingUpdate

  • maxSurge :此参数控制滚动更新过程,副本总数超过预期pod数量的上限。可以是百分比,也可以是具体的值。默认为1。
    (上述参数的作用就是在更新过程中,值若为3,那么不管三七二一,先运行三个pod,用于替换旧的pod,以此类推)
  • maxUnavailable:此参数控制滚动更新过程中,不可用的Pod的数量。 (这个值和上面的值没有任何关系,举个例子:我有十个pod,但是在更新的过程中,我允许这十个pod中最多有三个不可用,那么就将这个参数的值设置为3,在更新的过程中,只要不可用的pod数量小于或等于3,那么更新过程就不会停止)。

12. 常用的标签分类有哪些?

标签分类是可以自定义的,但是为了能使他人可以达到一目了然的效果,一般会使用以下一些分类:

  • 版本类标签(release):stable(稳定版)、canary(金丝雀版本,可以将其称之为测试版中的测试版)、beta(测试版);
  • 环境类标签(environment):dev(开发)、qa(测试)、production(生产)、op(运维);
  • 应用类(app):ui、as、pc、sc;
  • 架构类(tier):frontend(前端)、backend(后端)、cache(缓存);
  • 分区标签(partition):customerA(客户A)、customerB(客户B);
  • 品控级别(Track):daily(每天)、weekly(每周)。
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐