Files
kuboard-press/t/cka/daily/008.md
huanqing.shao b2402cde7d 010
2019-12-03 22:41:44 +08:00

5.6 KiB
Raw Blame History

vssueId, sharingTitle, description, meta
vssueId sharingTitle description meta
170 CKA备考打卡 - 每日一题 - Day 8 CKA备考打卡 - 每日一题 - Day 8
name content
keywords Kubernetes,K8S,CKA,Certified Kubernetes Administrator

CKA每日一题 --- Day 8

::: tip 考题

提供一个pod的yaml要求添加Init ContainerInit Container的作用是创建一个空文件pod的Containers判断文件是否存在不存在则退出

注意附带Pod完整yaml

:::

答案及解析

答案

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: cka-1126
  name: cka-1126
spec:
  initContainers:
  - image: busybox
    name: init-c
    command: ['sh', '-c', 'touch /tmp/cka-1126']
    volumeMounts:
    - name: workdir
      mountPath: "/tmp"
  containers:
  - image: busybox
    name: cka-1126
    command: ['sh', '-c', 'ls /tmp/cka-1126 && sleep 3600 || exit 1']
    volumeMounts:
    - name: workdir
      mountPath: "/tmp"
  volumes:
  - name: workdir
    emptyDir: {}

主Container的command就是判断文件是否存在存在则不退出不存在则退出也可以用以下if判断

command: ['sh', '-c', 'if [ -e /tmp/cka-1126 ];then echo "file exits";else echo "file not exits" && exit 1;fi']

解析

本题的关键点是init容器与主容器需要共同挂载一个名为workdir的目录init容器在里面创建一个空文件主容器去检验文件是否存在检验主要用的是shell的语法

command: ['sh', '-c', 'ls /tmp/cka-1126 && sleep 3600 || exit 1']

这句话意思是:如果ls /tmp/cka-1126返回码为0即文件存在将sleep 3600秒否则exit 1退出

也可以用shellif语法判断。

官方文档地址: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-initialization/

中文文档: https://kuboard.cn/learning/k8s-intermediate/workload/init-config.html

https://kubernetes.io/docs/concepts/workloads/pods/init-containers/

中文文档: https://kuboard.cn/learning/k8s-intermediate/workload/init-container.html

梳理概念

初始化容器顾名思义容器启动的时候会先启动可一个或多个容器如果有多个那么这几个Init Container按照定义的顺序依次执行一个执行成功才能执行下一个只有所有的Init Container执行完后主容器才会启动。由于一个Pod里的存储卷是共享的所以Init Container里产生的数据可以被主容器使用到。

Init Container可以在多种K8S资源里被使用到如Deployment、Daemon Set、StatefulSet、Job等但归根结底都是在Pod启动时在主容器启动前执行做初始化工作。

Init 容器支持应用容器的全部字段和特性包括资源限制、数据卷和安全设置。然而Init 容器不支持 Readiness Probe因为它们必须在 Pod 就绪之前运行完成;在资源限制、调度方面也会略有不同。

应用场景

等待其它模块Ready比如有一个应用里面有两个容器化的服务一个是Web Server另一个是数据库。其中Web Server需要访问数据库。但是当我们启动这个应用的时候并不能保证数据库服务先启动起来所以可能出现在一段时间内Web Server连接数据库错误。为了解决这个问题我们可以在运行Web Server服务的Pod里使用一个InitContainer去检查数据库是否准备好直到数据库可以连接Init Container才结束退出然后Web Server容器被启动发起正式的数据库连接请求。

初始化配置:比如集群里检测所有已经存在的成员节点,为主容器准备好集群的配置信息,这样主容器起来后就能用这个配置信息加入集群;目前在容器化,初始化集群配置文件时经常用到;

提供一种阻塞容器启动的方式必须在initContainer容器启动成功后才会运行下一个容器保证了一组条件运行成功的方式

其它使用场景将pod注册到一个中央数据库、下载应用依赖等。

Kubernetes 1.5 版本 开始支持在annotations下用pod.beta.kubernetes.io/init-containers申明initContainer像以下这样。

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
  annotations:
    pod.beta.kubernetes.io/init-containers: '[
        {
            "name": "init-myservice",
            "image": "busybox",
            "command": ["sh", "-c", "until nslookup myservice; do echo waiting for myservice; sleep 2; done;"]
        },
        {
            "name": "init-mydb",
            "image": "busybox",
            "command": ["sh", "-c", "until nslookup mydb; do echo waiting for mydb; sleep 2; done;"]
        }
    ]'
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']

Kubernetes 1.6 版本的新语法将 Init 容器的声明移到 spec 下,但是老的 annotation 语法仍然可以使用。

CKA 考试每日一题系列,全部内容由 我的小碗汤 创作,本站仅做转载