接下来我们说Kubernetes的工作负载
即WorkLoads
在官方文档中,工作负载是一个运行在Kubernetes上的一个应用程序
而在K8S上,如何表示一个应用程序的方式很多
从最小的Pod,到Deploy StatefulSet DaemonSet,整体的图如下
如果基于Pod搭建了更为上层的应用程序概念,那么Pod是具有自恢复能力的
那么我们自下往上开始,从Pod的书写开始,一步步的了解上层的概念
什么是Pod,是一组容器的集合,这些容器共享存储,网络,以及如何运行这个容器的声明
对于Pod的使用,一般不会直接创建,而是创建更为上层的对象来由他们来创建Pod
Pod对容器有自恢复能力
Pod自己不能恢复自己,但内部天然的共享了网络和存储
接下来我们看下Pod的标准写法
kind: Pod
apiVersion: v1 metadata: name: my-nginx-pod-test namespace: hello labels: aa: bb bb: dd spec: # 指定规格信息 containers: # 指定要启动一个什么样的容器 – image: nginx #指定镜像 name: my-nginx #容器的名字 |
其次,在Pod内部,可以包含多个容器,这一点毋庸置疑,在这多个容器中,主要的容器是主容器,其次配合主容器的容器,称为sidecar容器,就是带斗摩托车上的斗
对于两者,可以利用一些诸如文件系统,内存等进行交互
apiVersion: v1
kind: Pod metadata: name: “multi-container-pod” namespace: default labels: app: “multi-container-pod” spec: volumes: ### 以后见到的所有名字 都应该是一个合法的域名方式 – name: nginx-vol emptyDir: {} ### docker匿名挂载,外部创建一个位置 /abc containers: ## kubectl exec -it podName -c nginx-container(容器名)– /bin/sh – name: nginx-container image: “nginx” volumeMounts: #声明卷挂载 -v – name: nginx-vol mountPath: /usr/share/nginx/html – name: content-container image: “alpine” command: [“/bin/sh”,”-c”,”while true;do sleep 1; date > /app/index.html;done;”] volumeMounts: – name: nginx-vol mountPath: /app |
上面的yaml中
我们在声明了两个containers,分别是nginx和alpine
但是我们声明了两个volumeMounts,绑定同一个volume,一个绑定的nginx的html文件夹,一个是挂在根目录下的/app
这个volume是一个emptyDir,即生成一个本机的临时文件
然后由alpine负责每一秒将当前日期写入nginx的html中
这就是sidecar利用了Pod内部的存储互通的概念
其次在Pod中,除了自己声明的容器,K8S还会在容器中默认启动一个Pause容器
利用这个Pause容器,kubelet设置了网络和存储namespace,这也是为何在宿主机上删除对应的container,不会修改Pod相关配置,因为Pause没有改变
其关系可以利用宿主机上的systemctl status观测到
在整个Pod中,也是存在不同类型的container中的
在kubectl explain pod.spec 中,可以很清晰的看到
其中是包含initContainers containers ephemeralContainers
对于上面的容器,我们可以总结为下面的生命周期
在Pod启动的时候,会先启动init container,如果有一个失败,则Pod不能启动
接下来会启动所有的应用程序,如果有一个启动失败就会尝试启动Pod中的这个容器
那么我们如何尝试编写一个init container
apiVersion: v1
kind: Pod metadata: name: “pod-life-02” namespace: default labels: app: “pod-life-02” spec: volumes: – name: content-vol emptyDir: {} initContainers: ## Pod在启动containers之前,先要【运行完】initContainers的所有容器,所以这些容器必须有终结,不能一直运行 – name: init-c-01 image: alpine ### 必须有终结的那个时刻,一般不要用一直启动的镜像 command: [“/bin/sh”,”-c”,”echo 12222222 > /app/index.html;sleep 30;”] volumeMounts: – name: content-vol mountPath: /app # – name: init-c-02 # image: alpine ### 必须有终结的那个时刻,一般不要用一直启动的镜像 # command: [“/bin/sh”,”-c”,”echo 12222222 > /app/index.html;sleep 30;”] # volumeMounts: # – name: content-vol # mountPath: /app containers: ### docker run alpine 没有在后台一直启动的程序 – name: pod-life-01 image: “nginx” #默认的启动命令是启动nginx。nginx启动在后台一直有了 volumeMounts: – name: content-vol mountPath: /usr/share/nginx/html – name: pod-life-02 image: “alpine” #pod里面的containers都必须能启动起来,Pod会不断的重启这个容器 command: [“/bin/sh”,”-c”,”sleep 30″] |
上面的yaml中
我们声明了一个init container,需要注意的是服务container需要等待init container结束后才能启动,如果你的init container不结束自己,会导致pod永远不进入下一步
关于最后的临时容器,我们略微一提即可
对于临时容器,是用与进入这个Pod之中,进行Debug使用的
对于一般的容器,使用诸如busybox alpine这种容器,对于部署了Java环境的容器,可以考虑使用jdk
使用方式是声明一个临时容器,准备好json文件
{
“apiVersion”: “v1”, “kind”: “EphemeralContainers”, “metadata”: { “name”: “my-nginx666” //指定Pod的名字 }, “ephemeralContainers”: [{ “command”: [ “sh” ], “image”: “busybox”, //jre的需要jdk来调试 “imagePullPolicy”: “IfNotPresent”, “name”: “debugger”, “stdin”: true, “tty”: true, “terminationMessagePolicy”: “File” }] } |
上面过程中我们声明了一个image为busybox的临时容器,指定的对应Pod为my-nginx:666
对于使用
kubectl replace –raw /api/v1/namespaces/default/pods/my-nginx666【pod名】/ephemeralcontainers -f ec.json
之后我们说下K8S中Pod的探针机制
对于此,我们仍然选择kubectl explain来看
kubectl explain pod.spec.containers
其中有
livenessProbe, readinessProbe, startupProbe
startupProbe为启动探针,负责探测Pod是启动就绪的,如果一致没成功,就一直继续探测下,如果启动探针判断启动成功了之后,就不再继续探测了,交给存活探针和就绪探针运行了.
其的出现时为了解决存活探针和就绪探针何时启动的问题
livenessProbe,存活探针,判断容器是否正常存活,如果判断为失败就restart
readinessProbe,就绪探针,判断容器是否可以提供服务的,负责交给Service判断Pod是否提供服务的,如果某个Pod还没就绪,就从Service中剔除
内部的配置项可以利用explain来看
initialDelaySeconds <integer>
Number of seconds after the container has started before liveness probes
容器启动后多久才会初始化存活和就绪探测器,默认为0秒
periodSeconds <integer>
How often (in seconds) to perform the probe. Default to 10 seconds. Minimum
value is 1.
探测执行的间隔,默认为10,最小为1
successThreshold <integer>
Minimum consecutive successes for the probe to be considered successful
after having failed. Defaults to 1. Must be 1 for liveness and startup.
Minimum value is 1.
成功的最小连续成功数,默认值为1,最小值为1
failureThreshold <integer>
Minimum consecutive failures for the probe to be considered failed after
having succeeded. Defaults to 3. Minimum value is 1.
探测失败时候,Kubernetes的重试次数,失败之后就会重启容器,默认值为3,最小值为1
timeoutSeconds <integer>
Number of seconds after which the probe times out. Defaults to 1 second.
Minimum value is 1. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
探测超时后等地啊多少秒
除此外,探测的手段有
exec httpGet tcpSocket
需要注意的是,如果使用了httpGet的方式去探测的话
httpGet最好不要声明为127.0.0.1,kubelet可能会找错位置
可以直接不声明host来使用,这样kubelet会尝试查找Pod的对应的IP去访问