Kubernetes学习之初始化容器、钩子函数

一、初始化容器
  初始化容器(init container)即应用程序的主容器启动之前需要运行的容器,常用于为主容器执行一些预置的操作,它们具有两种典型特征:
  1)初始化容器必须运行完成直至结束,若某个初始化容器运行失败,那么Kubernetes需要重启此容器直到它成功启动
  2)每个初始化容器都必须按定义顺序的串行的来运行
Kubernetes学习之初始化容器、钩子函数_第1张图片
  有不少的场景都需要在应用容器启动之前进行部分初始化操作,例如,等待其他关联组件服务可用、基于环境变量或配置模板为应用程序生成配置文件、从配置中心获取配置等;初始化容器的典型应用需求具体包含如下几种:
  1)用于运行特定的工具程序,出于安全等方面的原因,这些程序不适用于包含在主容器镜像中
  2)提供主容器镜像中不具备的工具程序或自定义代码
  3)为容器镜像的构建和部署人员提供了分离、独立工作的途径,使得他们不必协同起来制作单个镜像文件
  4)初始化容器和主容器处于不同的文件系统视图中,因此可以分别安全地使用敏感数据,例如Secrets资源
  5)初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足

二、初始化容器实验

1)编写初始化容器yaml文件

]# cat init-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: init-pod
  labels:
    app: myapp
spec:
  containers:
  - name: init-conta
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
  initContainers:
  - name: init-something
    image: busybox
    command: ['sh','-c','sleep 10']

2)创建Pod

]# kubectl apply -f init-pod.yaml 
pod/init-pod created

3)观察集群中Pod的资源变化

]# kubectl get pod -w 
NAME       READY   STATUS    RESTARTS   AGE
init-pod   0/1     Pending   0          0s
init-pod   0/1     Pending   0          0s
init-pod   0/1     Init:0/1   0          0s

init-pod   0/1     Init:0/1   0          19s
init-pod   0/1     PodInitializing   0          29s
init-pod   1/1     Running           0          30s

]# kubectl get pods -o wide 
NAME       READY   STATUS     RESTARTS   AGE   IP       NODE    NOMINATED NODE   READINESS GATES
init-pod   0/1     Init:0/1   0          16s   <none>   node1   <none>           <none>

]# kubectl get pods -o wide 
NAME       READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
init-pod   1/1     Running   0          42s   10.244.1.39   node1   <none>           <none>

可以看到是先启动初始化容器的,待30秒之后再启动主容器,容器状态变为Running

4)查看Pod的详细信息

]# kubectl describe pods init-pod
Name:         init-pod
Namespace:    default
Priority:     0
Node:         node1/172.16.2.101
Start Time:   Sat, 01 Aug 2020 15:38:04 +0800
Labels:       app=myapp
Annotations:  Status:  Running
IP:           10.244.1.39
IPs:
  IP:  10.244.1.39
Init Containers:
  init-something:
    Container ID:  docker://f182b594a2541af05052a9fc5558c3b46c75e745135cd239962ae3e794efac71
    Image:         busybox
    Image ID:      docker-pullable://busybox@sha256:4f47c01fa91355af2865ac10fef5bf6ec9c7f42ad2321377c21e844427972977
    Port:          <none>
    Host Port:     <none>
    Command:
      sh
      -c
      sleep 10
    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Sat, 01 Aug 2020 15:38:23 +0800
      Finished:     Sat, 01 Aug 2020 15:38:33 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-47pch (ro)
Containers:
  init-conta:
    Container ID:   docker://5e883576bc8b3b7fe1f19c6057c8c7c9f386a1f19f98c469811d2e91c350365c
    Image:          ikubernetes/myapp:v1
    Image ID:       docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sat, 01 Aug 2020 15:38:34 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-47pch (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-47pch:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-47pch
    Optional:    false
QoS Class:       BestEffort
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  <unknown>  default-scheduler  Successfully assigned default/init-pod to node1
  Normal  Pulling    <invalid>  kubelet, node1     Pulling image "busybox"
  Normal  Pulled     <invalid>  kubelet, node1     Successfully pulled image "busybox"
  Normal  Created    <invalid>  kubelet, node1     Created container init-something
  Normal  Started    <invalid>  kubelet, node1     Started container init-something
  Normal  Pulled     <invalid>  kubelet, node1     Container image "ikubernetes/myapp:v1" already present on machine
  Normal  Created    <invalid>  kubelet, node1     Created container init-conta
  Normal  Started    <invalid>  kubelet, node1     Started container init-conta

从此Pod的详细信息中Init、Event字段中可以看出,先启动了busybox容器并在30秒之后正常退出了,然后再去启动init-pod

三、Pod生命周期钩子函数
  生命周期钩子函数(lifecycle hook)是编程语言(如Angular)中常用的生命周期管理的组件,它实现了程序运行周期中关键时刻的可见性,并赋予用户为此采取某种行为的能力。类似地,容器生命周期钩子使它能够感知其自身生命周期管理中的事件,并在相应的时刻到来时运行由用户指定的处理程序代码。Kubernetes为容器提供了两种生命周期钩子:
  1)postStart:于容器创建完成之后立即运行的钩子处理器(handler),不过Kubernetes无法确保它一定会于容器中ENTRYPOINT之前运行
  2)preStop:于容器终止操作之前立即运行的钩子处理器,它以同步的方式调用,因此在其完成之前会阻塞删除容器的操作的调用
Kubernetes学习之初始化容器、钩子函数_第2张图片
  钩子处理器的实现方式有"Exec"和"HTTP"两种,前一种在钩子事件触发时直接在当前容器中运行由用户定义的命令,后一种则是在当前容器中向某URL发起HTTP请求。

四、钩子函数实验

1)编写钩子函数yaml文件

]# cat lifecycle.yml 
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
  labels:
    app: myapp
    release: dev
spec:
  containers:
  - name: lifecycle-demo-container
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh","-c","echo 'lifecycle hooks handle' > /tmp/test.txt"]
      preStop:
        exec:
          command: ["/usr/sbin/nginx","-s","quit"]

2)进入容器查看测试文件

# kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
lifecycle-demo   1/1     Running   0          62s   10.244.1.40   node1   <none>           <none>

/ # cat /tmp/test.txt 
lifecycle hooks handle

可以看到有此文件,说明容器启动后执行了启动的钩子函数

3)退出Pod

]# kubectl delete -f lifecycle.yml 
pod "lifecycle-demo" deleted

你可能感兴趣的:(Kubernetes学习)