kubernetes快速入门5-Pod资源详谈

网友投稿 235 2022-10-27

kubernetes快速入门5-Pod资源详谈

kubernetes快速入门5-Pod资源详谈

pod只是逻辑上的概念,可以把pod看成一个容器,容器内跑的是一个或多个容器实体(docker容器)。Pod资源spec.containers对象说明

pod.spec.containers <[]Object> 字段: name 必选字段,表明容器名称 image 镜像地址 imagePullPolicy 镜像拉取策略,Always, Never, IfNotPresent 其中之一,当镜像的tag为latest时,默认为Always ports <[]Object> 暴露端口,是说明性信息,并不代表容器是否真正暴露端口,只要容器监听某个端口,集群内就能访问相应的服务 containerPort 必选项,容器暴露的端口号 name 起一个名称 command <[]string> 容器中执行的命令 args <[]string> 容器中为执行命令传递的参数,如果要引用变量使用“$(VAR_NAM)”,使用“$$(VAR_NAM)”为变量逃逸 说明:镜像中可能会有CMD和ENTRYPOINT两个字段,镜像中的ENTRYPOINT相当于k8s中的command,镜像中的CMD相当于k8s中的args,如果定义资源清单时也定义了command和args字段,这4个字段混合使用会产生不同的场景。官方已给了详细的说明:Kubernetes 对象(比如 Pods)上的键值对。标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象。标签可以在创建时附加到对象,随后可以随时添加和修改。

标签可以在多个维度上进行定义,如

"release" : "stable", "release" : "canary" # 以发布的版本为维度 "environment" : "dev", "environment" : "qa", "environment" : "production" # 发环境为维度 "tier" : "frontend", "tier" : "backend", "tier" : "cache" # 以层次为维度 "partition" : "customerA", "partition" : "customerB" # 以分区为维度 "track" : "daily", "track" : "weekly"

标签语法和字符集

标签 是键值对。有效的标签键有两个段:可选的前缀和名称,用斜杠(/)分隔。名称段是必需的,必须小于等于 63 个字符,以字母数字字符([a-z0-9A-Z])开头和结尾,带有破折号(-),下划线(_),点( .)和之间的字母数字。

有效标签值必须为 63 个字符或更少,并且必须为空或以字母数字字符([a-z0-9A-Z])开头和结尾,中间可以包含破折号(-)、下划线(_)、点(.)和字母或数字。

标签相关命令

显示标签

在k8s中使用kubectl get来获取某种资源时,在最后加上--show-lables选项就能显示该种资源的标签信息,如

$ kubectl get pods --show-lables $ kubectl get nodes --show-lables

过滤标签

-L, --label-columns=[] 显示某个资源指定标签的值,没有就为空

-l, --selector='' 过滤出指定的标签的资源

k8s@node01:~$ kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS myapp-dep-c988cf69-2dps2 1/1 Running 0 5h33m app=myapp-dep,pod-template-hash=c988cf69 myapp-dep-c988cf69-hjm8j 1/1 Running 0 5h33m app=myapp-dep,pod-template-hash=c988cf69 myapp-dep-c988cf69-j56hp 1/1 Running 0 5h33m app=myapp-dep,pod-template-hash=c988cf69 mynginx-deployment-646959f957-jqq67 1/1 Running 0 5h33m app=mynginx-deployment,pod-template-hash=646959f957 pod-demo 2/2 Running 0 48s app=myapp,tier=frontend k8s@node01:~$ kubectl get pods -L tier,app NAME READY STATUS RESTARTS AGE TIER APP myapp-dep-c988cf69-2dps2 1/1 Running 0 5h36m myapp-dep myapp-dep-c988cf69-hjm8j 1/1 Running 0 5h36m myapp-dep myapp-dep-c988cf69-j56hp 1/1 Running 0 5h36m myapp-dep mynginx-deployment-646959f957-jqq67 1/1 Running 0 5h36m mynginx-deployment pod-demo 2/2 Running 0 3m58s frontend myapp k8s@node01:~$ kubectl get pods -l tier NAME READY STATUS RESTARTS AGE pod-demo 2/2 Running 0 4m12s

打标签

k8s@node01:~$ kubectl label pods pod-demo release=canary # 给pod-demo这个pod对象打标签 pod/pod-demo labeled k8s@node01:~$ kubectl get pod pod-demo --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-demo 2/2 Running 0 7m52s app=myapp,release=canary,tier=frontend # 对已有标签重新打标签需要加了“--overwrite”选项 k8s@node01:~$ kubectl label pods pod-demo release=stable --overwrite pod/pod-demo labeled k8s@node01:~$ kubectl get pod pod-demo --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-demo 2/2 Running 0 10m app=myapp,release=stable,tier=frontend

标签选择器分类

基于等值关系的标签选择器

操作符: =或== 表示相等,!=表示不相等

k8s@node01:~$ kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS myapp-dep-c988cf69-2dps2 1/1 Running 0 5h52m app=myapp-dep,pod-template-hash=c988cf69,release=canary myapp-dep-c988cf69-hjm8j 1/1 Running 0 5h52m app=myapp-dep,pod-template-hash=c988cf69 myapp-dep-c988cf69-j56hp 1/1 Running 0 5h52m app=myapp-dep,pod-template-hash=c988cf69 mynginx-deployment-646959f957-jqq67 1/1 Running 0 5h52m app=mynginx-deployment,pod-template-hash=646959f957,release=canary pod-demo 2/2 Running 0 19m app=myapp,release=stable,tier=frontend k8s@node01:~$ kubectl get pods -l release==canary --show-labels NAME READY STATUS RESTARTS AGE LABELS myapp-dep-c988cf69-2dps2 1/1 Running 0 5h53m app=myapp-dep,pod-template-hash=c988cf69,release=canary mynginx-deployment-646959f957-jqq67 1/1 Running 0 5h53m app=mynginx-deployment,pod-template-hash=646959f957,release=canary k8s@node01:~$ kubectl get pods -l release=canary,app=myapp-dep --show-labels # 多个条件 NAME READY STATUS RESTARTS AGE LABELS myapp-dep-c988cf69-2dps2 1/1 Running 0 5h52m app=myapp-dep,pod-template-hash=c988cf69,release=canary k8s@node01:~$ kubectl get pods -l app!=myapp-dep --show-labels NAME READY STATUS RESTARTS AGE LABELS mynginx-deployment-646959f957-jqq67 1/1 Running 0 5h53m app=mynginx-deployment,pod-template-hash=646959f957,release=canary pod-demo 2/2 Running 0 20m app=myapp,release=stable,tier=frontend

基于集合关系的标签选择器

操作符号: in,notin,!

k8s@node01:~$ kubectl get pods -l "release in (canary, release, beta)" --show-labels NAME READY STATUS RESTARTS AGE LABELS myapp-dep-c988cf69-2dps2 1/1 Running 0 5h59m app=myapp-dep,pod-template-hash=c988cf69,release=canary mynginx-deployment-646959f957-jqq67 1/1 Running 0 5h59m app=mynginx-deployment,pod-template-hash=646959f957,release=canary k8s@node01:~$ kubectl get pods -l "release notin (canary, release, beta)" --show-labels NAME READY STATUS RESTARTS AGE LABELS myapp-dep-c988cf69-hjm8j 1/1 Running 0 5h59m app=myapp-dep,pod-template-hash=c988cf69 myapp-dep-c988cf69-j56hp 1/1 Running 0 5h59m app=myapp-dep,pod-template-hash=c988cf69 pod-demo 2/2 Running 0 27m app=myapp,release=stable,tier=frontend k8s@node01:~$ kubectl get pods -l "release" --show-labels # 显示有 release 标签的资源 NAME READY STATUS RESTARTS AGE LABELS myapp-dep-c988cf69-2dps2 1/1 Running 0 6h3m app=myapp-dep,pod-template-hash=c988cf69,release=canary mynginx-deployment-646959f957-jqq67 1/1 Running 0 6h3m app=mynginx-deployment,pod-template-hash=646959f957,release=canary pod-demo 2/2 Running 0 31m app=myapp,release=stable,tier=frontend k8s@node01:~$ kubectl get pods -l !"release" --show-labels # 不支持显示没有 release 标签的资源 -su: !"release": event not found

资源清单定义标签选择器

许多资源支持内嵌字段定义其使用的标签选择器

matchLable: 直接给定键值

mathExpressions: 基于给定的表达式来定义使用的标签选择器,格式为 {key: "KEY", operator: "OPERATOR", values: [VAL1, VAL2, ...]},表示 KEY这个键基于 [VAL1, VAL2, ...]这些值做 OPERATOR 比较。operator常用操作符号一般为In,NotIn,values必须为非空列表,Exists, NotExists,values必须为空列表。

pod的节点标签选择器

在pods.spec下有字段nodeSelector <map[string]string>,表示pod运行节点的倾向性,比如k8s集群内的工作节点配置不相同,一些节点有ssd磁盘,有些节点有比较大的内存或多颗cpu,这样可以针对各个节点的特点打上标签,然后在定义pod时使用节点选择器让pod更有倾向运行在打有相应标签的节点上。

在pods.spec下有字段nodeName <string>,表示让pod运行在指定的节点上

元数据annotations字段

pod.annotations 定义pod的注解信息。

annotations <map[string]string> 与label不同的地方在于它不能用于挑选资源对象,仅用于为对象提供元数据。

综合以上,对pods-demo.yaml文件进行修改

k8s@node01:~/my_manifests$ cat pods-demo.yaml apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend annotations: abc.com/created-by: "cluster admin" spec: containers: - name: app image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 - name: bbox image: busybox:latest imagePullPolicy: IfNotPresent command: - "/bin/sh" - "-c" - "sleep 3600" nodeName: node03

pod生命周期

pod创建过程

1. 通过kubectl向apiserver发送创建Pod资源的请求 2. apiserver把请求创建资源的目标状态保存在etcd中,apiserver请求scheduler进行调度,并把调度的结果(调度在哪个节点上)保存在pod信息相关etcd中 3. apiserver通知目标工作节点的kubelet有新的资源创建请求,并拿到相应的资源清单,根据清单在当前节点创建资源,并把相应的创建的状态信息发送回apiserver

pod状态:

Pending: 挂起状态,调度未完成 Running: 正常运行状态 Failed: 运行失败 Succeeded: 成功 Unknown: 工作节点kubelet出现故障,apiserver无法获取状态信息

Pod生命周期中的重要行为:

初始化容器,在创建Pod时需要先做容器的初始化操作 容器探测 探测有两种类型: liveness probe 存活性探测,用于探测容器是否处于存活状态 readiness probe 就绪性探测,用于探测容器中的程序是否能够正常提供服务 每种探测类型都支持3种探针: 1. ExecAction, 执行自定义的命令 2. TCPSockerAction, 向指定的tcp端口发请求 3. HTTPGetAction, 向指定的 One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy Always: 总是重启,其内部实现延时重启策略,如:第一次异常立刻重启,第二次重启就得等30秒,第三次重启就得等更长的时间,最多等待300秒重启 OnFailure:状态为错误时重启 Never:不管是什么原因永不重启

pod终止过程

kubectl delete -f FILE命令向apiserver发送任务,apiserver通知目标工作节点的kubelet对相应pod资源进行终止操作,先向pod中的容器发送terminal(15)信号,并有一个默认30秒的宽限期,如果能正常终止就终止pod,再如宽限期过后pod还无法终止,则再发送 kill(9)信号强制终止。

livenessProbe探测

使用kubectl explain pod.spec.containers.livenessProbe查看容器的存活性探测的帮助信息

livenessProbe FIELDS: exec exec类型探针 http类型探针 tcpSocket tcp类型探针 failureThreshold 探测几次才判断为失败,默认为3次 periodSeconds 每一次探测间隔时长,默认为10s successThreshold 判断为成功的次数,默认为1次 timeoutSeconds 每一次探测的超时时间,默认为1s initialDelaySeconds 容器启动后开始做探测等待时长,无默认值

exec探针

k8s@node01:~/my_manifests$ cat liveness-exec.yaml apiVersion: v1 kind: Pod metadata: name: liveness-exec-pod namespace: default spec: containers: - name: liveness-exec-container image: busybox:latest imagePullPolicy: IfNotPresent # 镜像tag为latest时镜像拉取策略都为Always command: ["/bin/sh", "-c", "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 3600"] livenessProbe: exec: command: ["test", "-e", "/tmp/healthy"] initialDelaySeconds: 1 periodSeconds: 3 # 应用yaml k8s@node01:~/my_manifests$ kubectl create -f liveness-exec.yaml pod/liveness-exec-pod created # 容器启动后等待1秒开始进行探测,前30秒探测为正常 k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE liveness-exec-pod 1/1 Running 0 21s # /tmp/healthy文件被删除后,探测失败,经过3个周期探测失败后,pod的默认restartPolicy为Always,容器会重启 k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE liveness-exec-pod 1/1 Running 2 2m42s # 当容器被重启次数过多时,状态为 CrashLoopBackOff k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE liveness-exec-pod 0/1 CrashLoopBackOff 5 7m16s

cat liveness-httpget.yaml apiVersion: v1 kind: Pod metadata: name: liveness-httpget-pod namespace: default spec: containers: - name: liveness-httpget-container image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: myapp-http containerPort: 80 livenessProbe: httpGet: port: myapp- # 可引用暴露端口的名称 path: / scheme: HTTP # 可省略,默认使用HTTP initialDelaySeconds: 1 periodSeconds: 3 k8s@node01:~/my_manifests$ kubectl create -f liveness-httpget.yaml pod/liveness-created # pod处于Running状态,正常 k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE liveness- 1/1 Running 0 2m36s # 连接至pod中的容器,手动删除主页文件 k8s@node01:~/my_manifests$ kubectl exec -it liveness--- /bin/sh / # rm -f /usr/share/nginx/html/ 50x.html index.html / # rm -f /usr/share/nginx/html/index.html / # command terminated with exit code 137 # 主机文件被删除后,httpget探测失败,容器被重启,退出容器连接 # pod被重启1次 k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE liveness- 1/1 Running 1 4m33s

tcpSocket探针

k8s@node01:~/my_manifests$ cat liveness-tcpsocket.yaml apiVersion: v1 kind: Pod metadata: name: liveness-tcpsokcet-pod namespace: default spec: containers: - name: liveness-tcpsokcet-container image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: myapp-http containerPort: 80 livenessProbe: tcpSocket: port: myapp- # 可引用暴露端口的名称 initialDelaySeconds: 1 periodSeconds: 3

readingProbe探测

为什么要做就绪性探测?

service是对外提供访问的固定端点,对其下的pods会进行负载调度,如果一个pod下运行了两个容器,现在因负载太大需要扩容为3个容器,第3个容器被创建成功后就立刻会被pod所关联进来进行调度,而容器内运行的程序可能需要一定的时间才能接受请求服务,而此时会有一部分流量被service分配到未就绪的第3个容器上,请求到该容器上的请求就会出问题,所以需要做就绪性探测,只有探测正常后service才分配流量到新的容器上。

readinessProbe探测同样支持exec, tcpSocket三种探针进行探针,定义格式也一样。

k8s@node01:~/my_manifests$ cat readiness-httpget.yaml apiVersion: v1 kind: Pod metadata: name: readiness-httpget-pod namespace: default spec: containers: - name: readiness-httpget-container image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: myapp-http containerPort: 80 readinessProbe: httpGet: port: myapp- # 可引用暴露端口的名称 path: / scheme: HTTP # 可省略,默认使用HTTP initialDelaySeconds: 1 periodSeconds: 3 k8s@node01:~/my_manifests$ kubectl create -f readiness-httpget.yaml pod/readiness-created k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE readiness- 1/1 Running 0 11s # 连接到Pod删除主页 k8s@node01:~/my_manifests$ kubectl exec -it readiness--- /bin/sh / # mv /usr/share/nginx/html/index.html /tmp/ / # # 删除主页后,REAY中就绪为0,容器主进程仍然在运行,容器不会被重启;如果再把主页还原,就绪状态就恢复 # k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE readiness- 0/1 Running 0 2m7s

lifecycle-生命周期勾子

pod中的容器在被启动后(postStart)可以立刻执行一些操作,当该操作执行成功后才接着做接下来的流程;pod中的容器在结束前preStop也可以先执行一此收尾操作,收尾操作完成后才结束pod的生命周期。

k8s@node01:~/my_manifests$ kubectl explain pod.spec.containers.lifecycle 说明: RESOURCE: lifecycle FIELDS: postStart preStop

postStart和preStop都支持exec, cat lifecycle-poststart.yaml apiVersion: v1 kind: Pod metadata: name: lifecycele-poststart-pod namespace: default spec: containers: - name: busybox-container image: busybox:latest command: ["/bin/sh", "-c", "sleep 3600"] lifecycle: postStart: exec: command: ['/bin/sh', "-c", "mkdir /tmp/lifecycle"] k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE lifecycele-poststart-pod 1/1 Running 0 10s # 检查 /tmp/lifecycle 目录是否存在 k8s@node01:~/my_manifests$ kubectl exec -it lifecycele-poststart-pod -- ls /tmp lifecycle

注意:

postStart中执行的操作与容器的command中执行的程序不要有强依赖性,如:容器的command运行httpd服务,并把家目录指向postStart中创建的一个目录,这样容器运行httpd命令时会出错,也就是容器是先执行自己的command中的命令,再运行postStart中定义的操作。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:揭秘Imagination 4级光追GPU和Vulkan绘图应用程序接口
下一篇:超声波无损检测系统的A/D与ARM接口设计
相关文章

 发表评论

暂时没有评论,来抢沙发吧~