Kubernetes K8S之Pod 生命周期与init container初始化容器详解

K8S中Pod的生命周期与init container初始化容器详解node

主机配置规划

服务器名称(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就能互相通讯。python

kubernetes中的pause容器主要为每一个业务容器提供如下功能:

PID命名空间:Pod中的不一样应用程序能够看到其余应用程序的进程ID。web

网络命名空间:Pod中的多个容器可以访问同一个IP和端口范围。api

IPC命名空间:Pod中的多个容器可以使用System V IPC或POSIX消息队列进行通讯。安全

UTS命名空间:Pod中的多个容器共享一个主机名;Volumes(共享存储卷)。服务器

Pod中的各个容器能够访问在Pod级别定义的Volumes。网络

Init Container容器

Pod能够包含多个容器,应用运行在这些容器里面,同时 Pod 也能够有一个或多个先于应用容器启动的 Init 容器。app

若是为一个 Pod 指定了多个 Init 容器,这些Init容器会按顺序逐个运行。每一个 Init 容器都必须运行成功,下一个才可以运行。当全部的 Init 容器运行完成时,Kubernetes 才会为 Pod 初始化应用容器并像日常同样运行。ide

Init容器与普通的容器很是像,除了如下两点:svg

一、Init容器老是运行到成功完成且正常退出为止

二、只有前一个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 容器是与应用容器分离的单独镜像,其启动相关代码具备以下优点:

一、Init 容器能够包含一些安装过程当中应用容器不存在的实用工具或个性化代码。例如,在安装过程当中要使用相似 sed、 awk、 python 或 dig 这样的工具,那么放到Init容器去安装这些工具;再例如,应用容器须要一些必要的目录或者配置文件甚至涉及敏感信息,那么放到Init容器去执行。而不是在主容器执行。

二、Init 容器能够安全地运行这些工具,避免这些工具致使应用镜像的安全性下降。

三、应用镜像的建立者和部署者能够各自独立工做,而没有必要联合构建一个单独的应用镜像。

四、Init 容器能以不一样于Pod内应用容器的文件系统视图运行。所以,Init容器可具备访问 Secrets 的权限,而应用容器不可以访问。

五、因为 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

完毕!


———END———
若是以为不错就关注下呗 (-^O^-) !

在这里插入图片描述