1、pod的共享资源
一个 Pod 中的应用容器共享五种资源:
- PID 命名空间:Pod 中的不同应用程序可以看到其他应用程序的进程 ID。
- 网络命名空间:Pod 中的多个容器能够访问同一个IP和端口范围。、
- IPC 命名空间:Pod 中的多个容器能够使用 SystemV IPC 或 POSIX 消息队列进行通信。
- UTS 命名空间:Pod 中的多个容器共享一个主机名。
- Volumes(共享存储卷):Pod 中的各个容器可以访问在 Pod 级别定义的 Volumes。
Pod 的生命周期通过 Replication Set 来管理;通过模板进行定义,然后分配到一个 Node
2、 k8s架构 每个组件的作用
master: etcd (分布式kv存储) apiserver (增删改etcd数据) controller-manager (监视资源变化,pod异常拉起) scheduler(调度资源)
worker: kube-proxy kubelet cri
组件: coredns cni(flannel calico) dashboard ingress
3、headless-service使用场景
自主选择权 client可以自主选择哪个server
Headless Service 的对应的每一个 Endpoints,即每一个Pod,都会有对应的DNS域名,这样Pod之间就可以互相访问。
4、集群使用的网络方案,pod如何和node网络通信的
Flannel
:使用vxlan技术为各节点创建一个可以互通的Pod网络,使用的端口为UDP 8472(需要开放该端口,如公有云AWS等)。flanneld第一次启动时,从etcd获取配置的Pod网段信息,为本节点分配一个未使用的地址段,然后创建flannedl.1网络接口(也可能是其它名称,如flannel1等)。flannel将分配给自己的Pod网段信息写入 /run/flannel/subnet.env
文件,docker后续使用这个文件中的环境变量设置docker0网桥,从而从这个地址段为本节点的所有Pod容器分配IP。
Calico
:在宿主机部署calico作为虚拟路由器,容器流量通过veth pair到达宿主机的网络命名空间上。
5、k8s集群节点需要关机维护,需要怎么操作
1、先cordon节点 即设置为不可调度 2、# 驱逐 node 节点上 pod $ kubectl drain k8s-node-01 --force --ignore-daemonsets 3、 关机 $ init 0
6、有哪些pod控制器
Pod控制器
:Deployment,ReplicationController,StatefulSet,DaemonSet,Cronjob,Job
7、存活性监测和就绪性监测的实现方式
存活性监测和就绪性监测的实现方式
:readiness probe,liveness probe:HTTP请求,TCP连接,命令行
8、pod如何平滑升级
minReadySeconds: 5 strategy: # indicate which strategy we want for rolling update type: RollingUpdate rollingUpdate: maxSurge: 30% maxUnavailable: 30%
9、存储卷使用方式
- 动态存储使用
storageclass
- 静态存储使用
persistentvolume
10、对外提供服务的pod暴露方式有哪些
hostNetwork:在pod中使用该配置,在这种Pod中运行的应用程序可以直接看到pod启动的主机的网络接口
hostPort:直接将容器的端口与所调度的节点上的端口路由,这样用户就可以通过主机的IP来访问Pod
NodePort:是K8s里一个广泛应用的服务暴露方式。K8s中的service默认情况都是使用Cluster IP这种类型,会产生一个只能在内部访问的Cluster IP,如果想能够直接访问service,需要将service type修改为nodePort。同时给改service指定一个nodeport值(30000-32767),用 --service-node-port-range 定义。
LoadBalancer:只能在service上定义,是公有云提供的负载均衡器
Ingress:ingress controller是由K8s管理的负载均衡容器,它的镜像包含一个nginx或HAProxy负载均衡器和一个控制器守护进程。
11、port targetPort nodePort
targetPort是pod内部应用使用端口
port是集群内部互访的dnat端口: clusterIp:port
nodePort是外部访问端口
12、上万规模的容器的kubernetes集群,使用kubernetes时需要注意哪些问题?
上万规模需要用ipvs做转发,网络用calico性能更好。
13、kubernetes的运维中有哪些注意的要点?
注意做好hpa,还有livenessProbe和readnessProbe这种探测,数据持久化,监控等
14、pause容器
我们看下在node节点上都会起很多pause容器,和pod是一一对应的。
每个Pod里运行着一个特殊的被称之为Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷,因此他们之间通信和数据交换更为高效,在设计时我们可以充分利用这一特性将一组密切相关的服务进程放入同一个Pod中。同一个Pod里的容器之间仅需通过localhost就能互相通信。
kubernetes中的pause容器主要为每个业务容器提供以下功能:
PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID。
网络命名空间:Pod中的多个容器能够访问同一个IP和端口范围。
IPC命名空间:Pod中的多个容器能够使用SystemV IPC或POSIX消息队列进行通信。
UTS命名空间:Pod中的多个容器共享一个主机名;
Volumes(共享存储卷):
Pod中的各个容器可以访问在Pod级别定义的Volumes。
15、一个经典Pod的完整生命周期是怎么样的? https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/
Pending
(悬决)Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间,
Running
(运行中)Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
Succeeded
(成功)Pod 中的所有容器都已成功终止,并且不会再重启。
Failed
(失败)Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。
Unknown
(未知)因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。
16、集群发生雪崩的条件,以及预防手段。
1、通过kubelet配置预留cpu 内存 磁盘资源
2、通过给每个应用配置request,limit,当节点资源不足时无法被调度
17 Kubernetes的网络实现
4.1 容器到容器的通信
- 同一个Pod内的容器共享同一个网络命名空间,直接使用localhost即可
4.2 Pod之间的通信
- 每个Pod都有一个真实的全局IP,每个Node内的不同Pod之间可以直接采用对方Pod的Ip通信
4.2.1 同一Node内Pod通信
- 同一Node内的Pod通过Veth设备对连接到同一个docker0网桥上,Pod的IP也都是该网桥分配的
- Pod内的默认路由都是docker0的地址,所有数据都通过docker0转发
4.2.2 不同Node的Pod通信
- Pod的地址是与docker0在同一个网段内,而docker0网段与宿主机网卡的IP网段完全不同,而通信只能走宿主机的网卡,因此通信必须通过宿主机IP来进行寻址和通信
- Kubernetes会记录所有正在运行Pod的IP分配信息,并将其写入etcd作为Service的Endpoint
- 支持不同Node之间Pod的通信条件:
- 整个Kubernetes集群中Pod的IP不能冲突
- 能将Pod的IP与Node的IP关联起来,通过这个关联实现相互访问,(注释:这一步是通过网络插件实现的 比如flannel会监控ECTD中每个Pod的实际地址,并在内存中建立维护Pod节点路由表)
- 解决:
- Kubernetes部署时多docker0的IP地址进行规划保证每个Node上的docker0地址不冲突
- 通信时先找到Node的IP将数据发送到这个网卡上,然后让宿主机将相应数据转到具体docker0上
4.3 Pod到Service的通信
- k8s在创建服务时为服务分配一个虚拟IP,客户端通过该IP访问服务,服务则负责将请求转发到后端Pod上
- Service是通过kube-proxy服务进程实现,该进程在每个Node上均运行可以看作一个透明代理兼负载均衡器
- 对每个TCP类型Service,kube-proxy都会在本地Node上建立一个SocketServer来负责接受请求,然后均匀发送到后端Pod默认采用Round Robin负载均衡算法
- Service的Cluster IP与NodePort等概念是kube-proxy通过Iptables的NAT转换实现,kube-proxy进程动态创建与Service相关的Iptables规则
- kube-proxy通过查询和监听API Server中Service与Endpoints的变化来实现其主要功能,包括为新创建的Service打开一个本地代理对象,接收请求针对针对发生变化的Service列表,kube-proxy会逐个处理,处理流程:
- 如果该Service没设置ClusterIP,则不做处理,否则获取该Service的所有端口定义列表
- 逐个读取端口定义列表,根据端口名、Service名和Namespace对其进行修改
- 更新负载均衡组件中对应Service的转发Service的转发地址列表
- 对于已删除的Service则进行清理
基础篇
基础篇主要面向的初级、中级开发工程师职位,主要考察对Kubernetes本身的理解。
- Kubernetes包含几个组件,各个组件的功能是什么,组件之间是如何交互的?
- Kubernetes的Pause容器有什么用,是否可以去掉?
- Kubernetes中的Pod内几个容器之间的关系是什么?
- 一个经典Pod的完整生命周期是怎么样的?
- Kubernetes的Service和ep是如何关联和相互影响的?
- 详述kube-proxy的工作原理,一个请求是如何经过层层转发落到某个Pod上的?注意请求可能来自Pod也可能来自外部。
- rc/rs功能是怎么实现的?请详述从API接收到一个创建rc/rs的请求,到最终在节点上创建Pod的全过程,尽可能详细。另外,当一个Pod失效时,Kubernetes是如何发现并重启另一个Pod的?
- deployment/rs有什么区别,其使用方式、使用条件和原理是什么?
- cgroup中的CPU有哪几种限制方式。Kubernetes是如何使用实现request和limit的?
拓展实践篇
拓展实践篇主要面向的高级开发工程师、架构师职位,主要考察实践经验和技术视野。
- 设想一个一千台物理机,上万规模容器的Kubernetes集群,请详述使用Kubernetes时需要注意哪些问题?应该怎样解决?(提示可以从高可用,高性能等方向,覆盖从镜像中心到Kubernetes各个组件等)
- 设想Kubernetes集群管理从一千台节点到五千台节点,可能会遇到什么样的瓶颈,应该如何解决?
- Kubernetes的运营中有哪些注意的要点?
- 集群发生雪崩的条件,以及预防手段。
- 设计一种可以替代kube-proxy的实现。
- Sidecar的设计模式如何在Kubernetes中进行应用,有什么意义?
- 灰度发布是什么,如何使用Kubernetes现有的资源实现灰度发布?
- 介绍Kubernetes实践中踩过的比较大的一个坑和解决方式。