Kubernetes Quick Start 5-Pod Resource Details
Pod is only a logical concept. You can think of pod as a container, in which one or more container entities (docker containers) run. Pod resource spec.containers
object description
pod.spec.containers <[]Object>
字段:
name <string> 必选字段,表明容器名称
image <string> 镜像地址
imagePullPolicy <string> 镜像拉取策略,Always, Never, IfNotPresent 其中之一,当镜像的tag为latest时,默认为Always
ports <[]Object> 暴露端口,是说明性信息,并不代表容器是否真正暴露端口,只要容器监听某个端口,集群内就能访问相应的服务
containerPort <integer> 必选项,容器暴露的端口号
name <string> 起一个名称
command <[]string> 容器中执行的命令
args <[]string> 容器中为执行命令传递的参数,如果要引用变量使用“$(VAR_NAM)”,使用“$$(VAR_NAM)”为变量逃逸
说明:镜像中可能会有CMD和ENTRYPOINT两个字段,镜像中的ENTRYPOINT相当于k8s中的command,镜像中的CMD相当于k8s中的args,如果定义资源清单时也定义了command和args字段,这4个字段混合使用会产生不同的场景。官方已给了详细的说明:https://kubernetes.io/zh/docs/tasks/inject-data-application/define-command-argument-container/
Tags and tag selector
Official document reference: https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/labels/
Labels are key-value pairs attached to Kubernetes objects (such as Pods). Labels are intended to specify the identification attributes of objects that are meaningful and relevant to users, but do not directly have semantic meaning to the core system. Tags can be used to organize and select objects. Tags can be attached to objects when they are created, and can be added and modified at any time afterwards.
Labels can be defined in multiple dimensions, such as
"release" : "stable", "release" : "canary" # 以发布的版本为维度
"environment" : "dev", "environment" : "qa", "environment" : "production" # 发环境为维度
"tier" : "frontend", "tier" : "backend", "tier" : "cache" # 以层次为维度
"partition" : "customerA", "partition" : "customerB" # 以分区为维度
"track" : "daily", "track" : "weekly"
Label syntax and character set
Tags are key-value pairs. A valid tag key has two segments: optional prefix and name, /
separated by a slash ( ). The name segment is required, must be less than or equal to 63 characters, [a-z0-9A-Z]
start and end with an alphanumeric character ( ), with a dash ( -
), underscore ( _
), dot ( .
) and alphanumeric characters in between.
The valid label value must be 63 characters or less, and must be empty or [a-z0-9A-Z]
start and end with an alphanumeric character ( ), and can include dash ( -
), underscore ( _
), dot ( .
), and letters or numbers in the middle .
Label related commands
Show label
When used in k8s kubectl get
to obtain a certain resource, adding an --show-lables
option at the end can display the label information of the resource, such as
$ kubectl get pods --show-lables
$ kubectl get nodes --show-lables
Filter tags
-L, --label-columns=[]
Display the value of the specified tag of a resource, or empty if not
-l, --selector=''
Filter out resources with specified tags
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
Tagging
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
Tag selector classification
Label selector based on equivalence relationship
Operator: =
or ==
means equal, !=
means not equal
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
Label selector based on set relationship
Operation in
symbol: 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
Resource list definition tag selector
Many resources support inline fields to define the label selector used
matchLable: Give the key directly
mathExpressions: Define the label selector used based on the given expression, the format is {key: "KEY", operator: "OPERATOR", values: [VAL1, VAL2, ...]}, which means that the KEY key is based on [ VAL1, VAL2, ...] These values are compared with OPERATOR. The common operation symbols of operator are generally In,NotIn
, values must be a non-empty list, Exists, NotExists
and values must be an empty list.
Node label selector for pod
In pods.spec
case there is a field nodeSelector <map[string]string>
indicating the tendency pod running node, such as working node cluster configurations within k8s not the same, there are some nodes ssd disk, there are some relatively large memory nodes or more satellites cpu, which can be marked with the characteristics of each node Label, and then use the node selector when defining the pod to make the pod more likely to run on the node with the corresponding label.
In pods.spec
case there is a field nodeName <string>
, let pod represents running on the specified node
Metadata annotations field
pod.annotations
Define the annotation information of the pod.
annotations <map[string]string>
The difference from label is that it cannot be used to select resource objects, only to provide objects 元数据
.
Based on the above, modify the pods-demo.yaml file
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 life cycle
Pod creation process
1. 通过kubectl向apiserver发送创建Pod资源的请求
2. apiserver把请求创建资源的目标状态保存在etcd中,apiserver请求scheduler进行调度,并把调度的结果(调度在哪个节点上)保存在pod信息相关etcd中
3. apiserver通知目标工作节点的kubelet有新的资源创建请求,并拿到相应的资源清单,根据清单在当前节点创建资源,并把相应的创建的状态信息发送回apiserver
Pod status:
Pending: 挂起状态,调度未完成
Running: 正常运行状态
Failed: 运行失败
Succeeded: 成功
Unknown: 工作节点kubelet出现故障,apiserver无法获取状态信息
Important behaviors in the Pod life cycle:
-
Initialize the container, you need to initialize the container first when creating a Pod
-
Container detection
探测有两种类型: liveness probe 存活性探测,用于探测容器是否处于存活状态 readiness probe 就绪性探测,用于探测容器中的程序是否能够正常提供服务 每种探测类型都支持3种探针: 1. ExecAction, 执行自定义的命令 2. TCPSockerAction, 向指定的tcp端口发请求 3. HTTPGetAction, 向指定的http服务发请求
Pod restart strategy
pod.spec
There are fields underrestartPolicy
restartPolicy <string>
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 termination process
kubectl delete -f FILE
The command sends a task to the apiserver, and the apiserver notifies the kubelet of the target worker node to terminate the corresponding pod resource. First, it sends the terminal(15) signal to the container in the pod, and there is a default grace period of 30 seconds. If it can be terminated normally, it will terminate The pod, if the pod cannot be terminated after the grace period, send the kill(9) signal to force termination.
livenessProbe detection
Use kubectl explain pod.spec.containers.livenessProbe
help information for viewing container viability detection
livenessProbe <Object>
FIELDS:
exec <Object> exec类型探针
httpGet <Object> http类型探针
tcpSocket <Object> tcp类型探针
failureThreshold <integer> 探测几次才判断为失败,默认为3次
periodSeconds <integer> 每一次探测间隔时长,默认为10s
successThreshold <integer> 判断为成功的次数,默认为1次
timeoutSeconds <integer> 每一次探测的超时时间,默认为1s
initialDelaySeconds <integer> 容器启动后开始做探测等待时长,无默认值
exec probe
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
httpGet probe
k8s@node01:~/my_manifests$ 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-http # 可引用暴露端口的名称
path: /
scheme: HTTP # 可省略,默认使用HTTP
initialDelaySeconds: 1
periodSeconds: 3
k8s@node01:~/my_manifests$ kubectl create -f liveness-httpget.yaml
pod/liveness-httpget-pod created
# pod处于Running状态,正常
k8s@node01:~/my_manifests$ kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness-httpget-pod 1/1 Running 0 2m36s
# 连接至pod中的容器,手动删除主页文件
k8s@node01:~/my_manifests$ kubectl exec -it liveness-httpget-pod -- /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-httpget-pod 1/1 Running 1 4m33s
tcpSocket probe
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-http # 可引用暴露端口的名称
initialDelaySeconds: 1
periodSeconds: 3
readingProbe
Why do readiness detection?
The service is a fixed endpoint that provides external access. The pods under it will perform load scheduling. If two containers are running under one pod, the capacity needs to be expanded to 3 containers due to the heavy load. After the third container is created successfully It will be immediately associated with the pod for scheduling, and the program running in the container may take a certain time to receive the requested service, and at this time, a part of the traffic will be allocated to 未就绪
the third container by the service, and the request will be sent to the container. There will be problems with the request, so readiness detection is required. Only after the detection is normal, the service will allocate traffic to the new container.
The readinessProbe probe also supports exec, httpGet, tcpSocket
three probes for probes, and the definition format is the same.
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-http # 可引用暴露端口的名称
path: /
scheme: HTTP # 可省略,默认使用HTTP
initialDelaySeconds: 1
periodSeconds: 3
k8s@node01:~/my_manifests$ kubectl create -f readiness-httpget.yaml
pod/readiness-httpget-pod created
k8s@node01:~/my_manifests$ kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness-httpget-pod 1/1 Running 0 11s
# 连接到Pod删除主页
k8s@node01:~/my_manifests$ kubectl exec -it readiness-httpget-pod -- /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-httpget-pod 0/1 Running 0 2m7s
lifecycle-life cycle hook
The container in the pod 启动后(postStart)
can perform some operations immediately. When the operation is successfully performed, the next process 结束前preStop
can be performed ; the container in the pod can also perform this first 收尾操作
, and the life cycle of the pod is ended after the finishing operation is completed.
k8s@node01:~/my_manifests$ kubectl explain pod.spec.containers.lifecycle
说明:
RESOURCE: lifecycle <Object>
FIELDS:
postStart <Object>
preStop <Object>
postStart
And preStop
supports exec, httpGet和tcpSocket
three types of probes.
k8s@node01:~/my_manifests$ 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
note:
postStart
The operations performed in the container command
should not have a strong dependency on the program executed in the container. For example, the container command
runs the httpd service and points the home directory to postStart
a directory created in the container, so that an error will occur when the container runs the httpd command, that is, the container is first Execute command
the command in your own , and then run the operation postStart
defined in.