Kubernetes K8S之Pod 生命周期与init container初始化容器详解
K8S中Pod的生命周期与init container初始化容器详解
主机配置规划
服务器名称(hostname) | 系统版本 | 配置 | 内网IP | 外网IP(模拟) |
---|---|---|---|---|
k8s-master | CentOS7.7 | 2C/4G/20G | 172.16.1.110 | 10.0.0.110 |
k8s-node01 | CentOS7.7 | 2C/4G/20G | 172.16.1.111 | 10.0.0.111 |
k8s-node02 | CentOS7.7 | 2C/4G/20G | 172.16.1.112 | 10.0.0.112 |
Pod容器生命周期
Pause容器说明
每个Pod里运行着一个特殊的被称之为Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷,因此他们之间通信和数据交换更为高效。在设计时可以充分利用这一特性,将一组密切相关的服务进程放入同一个Pod中;同一个Pod里的容器之间仅需通过localhost就能互相通信。
kubernetes中的pause容器主要为每个业务容器提供以下功能:PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID。
网络命名空间:Pod中的多个容器能够访问同一个IP和端口范围。
IPC命名空间:Pod中的多个容器能够使用System V IPC或POSIX消息队列进行通信。
UTS命名空间:Pod中的多个容器共享一个主机名;Volumes(共享存储卷)。
Pod中的各个容器可以访问在Pod级别定义的Volumes。
Init Container容器
Pod可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
如果为一个 Pod 指定了多个 Init 容器,这些Init容器会按顺序逐个运行。每个 Init 容器都必须运行成功,下一个才能够运行。当所有的 Init 容器运行完成时,Kubernetes 才会为 Pod 初始化应用容器并像平常一样运行。
Init容器与普通的容器非常像,除了以下两点:
1、Init容器总是运行到成功完成且正常退出为止
2、只有前一个Init容器成功完成并正常退出,才能运行下一个Init容器。
如果Pod的Init容器失败,Kubernetes会不断地重启Pod,直到Init容器成功为止。但如果Pod对应的restartPolicy为Never,则不会重新启动。
在所有的 Init 容器没有成功之前,Pod 将不会变成 Ready 状态。 Init 容器的端口将不会在 Service 中进行聚集。 正在初始化中的 Pod 处于 Pending 状态,但会将条件 Initializing 设置为 true。
如果 Pod 重启,所有 Init 容器必须重新执行。
在 Pod 中的每个应用容器和 Init 容器的名称必须唯一;与任何其它容器共享同一个名称,会在校验时抛出错误。
Init 容器能做什么?
因为 Init 容器是与应用容器分离的单独镜像,其启动相关代码具有如下优势:
1、Init 容器可以包含一些安装过程中应用容器不存在的实用工具或个性化代码。例如,在安装过程中要使用类似 sed、 awk、 python 或 dig 这样的工具,那么放到Init容器去安装这些工具;再例如,应用容器需要一些必要的目录或者配置文件甚至涉及敏感信息,那么放到Init容器去执行。而不是在主容器执行。
2、Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
3、应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
4、Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。
5、由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。
Init 容器示例
下面的例子定义了一个具有 2 个 Init 容器的简单 Pod。 第一个等待 myservice 启动,第二个等待 mydb 启动。 一旦这两个 Init容器都启动完成,Pod 将启动spec区域中的应用容器。
Pod yaml文件
[root@k8s-master lifecycle]# pwd /root/k8s_practice/lifecycle [root@k8s-master lifecycle]# cat init_C_pod.yaml apiVersion: v1 kind: Pod metadata: name: myapp-busybox-pod labels: app: myapp spec: containers: - name: myapp-container image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24 command: ['sh', '-c', "until nslookup myservice; do echo waiting for myservice; sleep 60; done"] - name: init-mydb image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24 command: ['sh', '-c', "until nslookup mydb; do echo waiting for mydb; sleep 60; done"]
启动这个 Pod,并检查其状态,可以执行如下命令:
[root@k8s-master lifecycle]# kubectl apply -f init_C_pod.yaml pod/myapp-busybox-pod created [root@k8s-master lifecycle]# kubectl get -f init_C_pod.yaml -o wide # 或者kubectl get pod myapp-busybox-pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-busybox-pod 0/1 Init:0/2 0 55s 10.244.4.16 k8s-node01 <none> <none>
如需更详细的信息:
[root@k8s-master lifecycle]# kubectl describe pod myapp-busybox-pod Name: myapp-busybox-pod Namespace: default Priority: 0 ………… Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m18s default-scheduler Successfully assigned default/myapp-busybox-pod to k8s-node01 Normal Pulled 2m17s kubelet, k8s-node01 Container image "registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24" already present on machine Normal Created 2m17s kubelet, k8s-node01 Created container init-myservice Normal Started 2m17s kubelet, k8s-node01 Started container init-myservice
如需查看Pod内 Init 容器的日志,请执行:
[root@k8s-master lifecycle]# kubectl logs -f --tail 500 myapp-busybox-pod -c init-myservice # 第一个 init container 详情 Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local waiting for myservice nslookup: can't resolve 'myservice' Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local ……………… [root@k8s-master lifecycle]# kubectl logs myapp-busybox-pod -c init-mydb # 第二个 init container 详情 Error from server (BadRequest): container "init-mydb" in pod "myapp-busybox-pod" is waiting to start: PodInitializing
此时Init 容器将会等待直至发现名称为mydb和myservice的 Service。
Service yaml文件
[root@k8s-master lifecycle]# pwd /root/k8s_practice/lifecycle [root@k8s-master lifecycle]# cat init_C_service.yaml --- kind: Service apiVersion: v1 metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- kind: Service apiVersion: v1 metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377
创建mydb和myservice的 service 命令:
[root@k8s-master lifecycle]# kubectl create -f init_C_service.yaml service/myservice created service/mydb created
之后查看pod状态和service状态,能看到这些 Init容器执行完毕后,随后myapp-busybox-pod的Pod转移进入 Running 状态:
[root@k8s-master lifecycle]# kubectl get svc -o wide mydb myservice NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR mydb ClusterIP 10.108.24.84 <none> 80/TCP 72s <none> myservice ClusterIP 10.105.252.196 <none> 80/TCP 72s <none> [root@k8s-master lifecycle]# [root@k8s-master lifecycle]# kubectl get pod myapp-busybox-pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-busybox-pod 1/1 Running 0 7m33s 10.244.4.17 k8s-node01 <none> <none>
由上可知:一旦我们启动了 mydb 和 myservice 这两个 Service,我们就能够看到 Init 容器完成,并且 myapp-busybox-pod 被创建。
进入myapp-busybox-pod容器,并通过nslookup查看这两个Service的DNS记录。
[root@k8s-master lifecycle]# kubectl exec -it myapp-busybox-pod sh / # nslookup mydb Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: mydb Address 1: 10.108.24.84 mydb.default.svc.cluster.local / # / # / # / # nslookup myservice Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: myservice Address 1: 10.105.252.196 myservice.default.svc.cluster.local
完毕!
- Kubernetes1.3新特性:POD中的初始化容器
- Kubernetes1.3新特性:POD中的初始化容器
- 视频教程-Linux架构师/2019年docker、k8s(kubernetes)容器技术最新详解-Linux
- Kubernetes K8S之Pod生命周期与探针检测
- Spring IOC源码详解之容器初始化
- 【LeetCode】详解盛最多水的容器11. Container With Most Water Given n non-negative integers a1, a2, ..., an
- Kubernetes——自动扩展容器!假设你突然需要增加你的应用;你只需要告诉deployment一个新的 pod 副本总数即可
- xinit命令_Linux xinit 命令用法详解:是Linux下X-Window系统的初始化程序
- SpringFramework学习-(4)IOC容器初始化过程详解
- STM32时钟初始化函数SystemInit()详解
- Spring的IOC、Spring对象初始化bean时机、Spring容器生命周期
- Spring IOC源码详解之容器初始化
- Kubernetes(K8s)容器设计模式实践案例 单节点多容器模式
- 【K8S】kubernetes集群外部访问Pod或Service
- vue webpack初始化项目(vue init webpack my-project )参数详解
- StringBuilder 和 常用容器初始化容量--性能--详解
- Kubernetes 1.5 实践 如何给pod中的容器设置环境变量
- kubernetes之Pod详解
- kubernetes_02_资源清单_02_Pod生命周期_20190918
- 第六章:STM32时钟初始化函数SystemInit()详解