目录
一、概述
二、使用InitContainer
InitContainer即初始化容器,是 K8S官方为我们提供的一个可以用来判断环境是否已经满足运行 Pod 应用前所需要的条件。
比如我们有一个应用,需要部署到Tomcat环境,那么在部署这个应用Pod之前,我们需要检查Tomcat环境是否已经准备好,InitContainer就可以用来做这个事情,我们可以让InitContainer运行 until 命令进行判断,判断是否满足我们应用运行的要求,如果满足运行要求,执行成功后便会退出,否则将会一直进行循环操作,直到条件成功。
使用InitContainer的一些优势:
创建 Pod 的资源清单文件: vim init-container-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
initContainers: # 支持配置多个初始化容器,当前面的初始化容器运行成功后,便会进行退出操作,紧接着启动下一个容器。
- name: my-init-container
image: busybox:1.28
# 通过until命令判断是否已经存在了名称为tomcat的Service,只有存在了tomcat,nginx这个Pod才能够启动成功
command: [ 'sh', '-c', 'until nslookup tomcat;do echo Waiting for Tomcat Service started...;sleep 60;done;' ]
containers:
- name: nginx
image: nginx
如上,我们通过在spec.initContainers指定了初始化容器,并且通过" until nslookup tomcat" 去检查当前是否已经存在名称为tomcat的service,只有存在tomcat service,初始化容器才会退出。如果 Pod 的InitContainer执行失败,kubelet 会不断地重启该InitContainer直到该容器成功为止。但是,如果 Pod 对应的 restartPolicy 值为 "Never",并且 Pod 的InitContainer失败, 则 Kubernetes 会将整个 Pod 状态设置为失败。
创建并查看Pod:
$ kubectl apply -f init-container-demo.yaml
deployment.apps/nginx created
# nginx pod一直处于Init:0/1,因为此时在执行initContainer的判断
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-7597c5f657-xfsvt 0/1 Init:0/1 0 4s
# 当前不存在tomcat service
$ kubectl get svc tomcat
Error from server (NotFound): services "tomcat" not found
# 查看my-init-container容器日志, 输出"Waiting for Tomcat Service started..."
$ kubectl logs nginx-7597c5f657-xfsvt -c my-init-container
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Waiting for Tomcat Service started...
nslookup: can't resolve 'tomcat'
下面我们创建一个tomcat的service:
$ kubectl create service clusterip tomcat --tcp=8080
service/tomcat created
$ kubectl get svc tomcat
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
tomcat ClusterIP 10.104.182.210 8080/TCP 3s
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-7597c5f657-xfsvt 1/1 Running 0 2m6s
可以看到,当创建完tomcat service后,InitContainer将会等待至发现名称为tomcat的Service,判断成功后,退出初始化容器,然后nginx这个Pod就运行成功了。
当然,我们可以为一个 Pod 指定了多个InitContainer,这些容器会按顺序逐个运行。 每个InitContainer必须运行成功,下一个才能够运行。当所有的InitContainer运行完成时, Kubernetes才会为Pod 初始化应用容器,然后运行起来。配置大体如下:
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers: # Init容器将会等待至发现名称为 mydb 和 myservice 的 Service
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]