4、kubernetes之Pod应用进阶
第四部分 Pod应用进阶
1、资源配置清单
自主式Pod资源
资源的清单格式:
一级字段:apiVersion(group/version),kind,netadata(name,namespace,labels,annotations,...),spec,status(只读)
Pod资源:
spec.container <[]object>
- name <string>
image <string>
imagePullPolicy <string>
Always(默认方式,每次启动都要从仓库去拉取镜像,比较费时), Never, IfNotPresent(本地不存在就去仓库下载镜像,缺点是latest镜像更新后,他不去主动更新)
修改镜像中的默认应用:command、args
参考:https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/
标签:
key=value
key:字母,数字,——、-、.
value:可以为空,只能字母或数字开头及结尾,中间可以使用
标签选择器:
等值关系:=,==,!=
集合关系:KEY in (value1,value2,...)
KEY notin (value1,value2,...)
KEY
! KEY
许多资源支持内嵌字段定义其使用的标签选择器:
matchLabels:直接使用给定键值
matchExpressions:基于给定的表达式来定义使用标签选择器,{key:'',operator:'OPRRAOR',values:[VAL1,VAL2,...]}
操作符:
In,NotIn: values字段的值必须为非空列表
Exists,NotExists:values字段的值必须为空列表;
nodeSelector,节点标签选择器,针对打标签的node节点进行选择
nodeName,节点名称,不常用。
annotations,与labels不同的地方,它不能用于挑选资源对象,仅用于对象提供“元数据”
$ kubectl explain pods.spec.containers
2、标签使用
a、多个标签查询,多个标签过滤
$ kubectl get pods --show-labels
$ kubectl get pods -l app --show-labels
$ kubectl get pods -L app
$ kubectl get pods -L app,run
$ kubectl get pods -l "relesae in (beta,stable,alpha)" --show-labels
$ kubectl get pods -l "relesae notin (beta,stable,alpha)" --show-labels
$ kubectl get pods -l "relesae" --show-labels
$ kubectl get pods -l "! relesae" --show-labels
[root@k8s-master ~]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS myapp-86984b4c7c-mjlsj 1/1 Running 0 5h56m pod-template-hash=86984b4c7c,run=myapp myapp-86984b4c7c-n4mcj 1/1 Running 0 5h56m pod-template-hash=86984b4c7c,run=myapp myapp-86984b4c7c-t4c56 1/1 Running 0 5h56m pod-template-hash=86984b4c7c,run=myapp myappx 2/2 Running 3 3h35m app=pod-demo,tier=frontend nginx-deploy-55d8d67cf-kcrhs 1/1 Running 0 7h16m pod-template-hash=55d8d67cf,run=nginx-deploy test-64585fcd47-2pwbk 1/1 Running 0 7h10m pod-template-hash=64585fcd47,run=test [root@k8s-master ~]# kubectl get pods -l app --show-labels NAME READY STATUS RESTARTS AGE LABELS myappx 2/2 Running 3 3h35m app=pod-demo,tier=frontend [root@k8s-master ~]# kubectl get pods -L app NAME READY STATUS RESTARTS AGE APP myapp-86984b4c7c-mjlsj 1/1 Running 0 5h56m myapp-86984b4c7c-n4mcj 1/1 Running 0 5h56m myapp-86984b4c7c-t4c56 1/1 Running 0 5h56m myappx 2/2 Running 3 3h35m pod-demo nginx-deploy-55d8d67cf-kcrhs 1/1 Running 0 7h16m test-64585fcd47-2pwbk 1/1 Running 0 7h10m [root@k8s-master ~]# kubectl get pods -L app,run NAME READY STATUS RESTARTS AGE APP RUN myapp-86984b4c7c-mjlsj 1/1 Running 0 5h57m myapp myapp-86984b4c7c-n4mcj 1/1 Running 0 5h57m myapp myapp-86984b4c7c-t4c56 1/1 Running 0 5h57m myapp myappx 2/2 Running 3 3h36m pod-demo nginx-deploy-55d8d67cf-kcrhs 1/1 Running 0 7h17m nginx-deploy test-64585fcd47-2pwbk 1/1 Running 0 7h11m test
b、标签新增或覆盖使用
$ kubectl label pods myappx relesae=canary
$ kubectl label pods myappx relesae=stable --overwrite
$ kubectl get pods -l relesae=stable --show-labels
$ kubectl get pods -l relesae=stable,app=pod-demo --show-labels
$ kubectl get pods -l relesae=stable,app!=pod-dem --show-labels
[root@k8s-master ~]# kubectl get pods -l app --show-labels NAME READY STATUS RESTARTS AGE LABELS myappx 2/2 Running 3 3h42m app=pod-demo,tier=frontend [root@k8s-master ~]# kubectl label pods myappx relesae=canary pod/myappx labeled [root@k8s-master ~]# kubectl get pods -l app --show-labels NAME READY STATUS RESTARTS AGE LABELS myappx 2/2 Running 3 3h43m app=pod-demo,relesae=canary,tier=frontend [root@k8s-master ~]# kubectl label pods myappx relesae=stable error: 'relesae' already has a value (canary), and --overwrite is false [root@k8s-master ~]# kubectl label pods myappx relesae=stable --overwrite pod/myappx labeled [root@k8s-master ~]# kubectl get pods -l app --show-labels NAME READY STATUS RESTARTS AGE LABELS myappx 2/2 Running 3 3h43m app=pod-demo,relesae=stable,tier=frontend [root@k8s-master ~]# kubectl get pods -l relesae=stable --show-labels NAME READY STATUS RESTARTS AGE LABELS myappx 2/2 Running 3 3h46m app=pod-demo,relesae=stable,tier=frontend
c、节点标记
添加节点资源的时候,可以针对标签给定适当资源。nodeSelector节点标签选择器
[root@k8s-master ~]# kubectl get no --show-labels NAME STATUS ROLES AGE VERSION LABELS k8s-master Ready master 15h v1.14.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/master= k8s-node1 Ready <none> 15h v1.14.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux k8s-node2 Ready <none> 9h v1.14.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux [root@k8s-master ~]# kubectl label nodes k8s-node1 disktype=ssd node/k8s-node1 labeled [root@k8s-master ~]# kubectl get no --show-labels NAME STATUS ROLES AGE VERSION LABELS k8s-master Ready master 15h v1.14.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/master= k8s-node1 Ready <none> 15h v1.14.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux k8s-node2 Ready <none> 9h v1.14.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux
pod创建过程直接nodeSelector选择器,挑选合适的node节点。
[root@k8s-master ~]# cat /root/yas/pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
tier: frontend
annotations:
k8s.mastet/create-by: "sunny wei"
spec:
containers:
- image: ikubernetes/myapp:v1
name: myapp
- image: busybox:latest
name: busybox
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
nodeSelector:
disktype: ssd
[root@k8s-master ~]# kubectl delete -f /root/yas/pod-demo.yaml
[root@k8s-master ~]# kubectl apply -f /root/yas/pod-demo.yaml
pod/pod-demo created
[root@k8s-master ~]# kubectl get pods pod-demo
NAME READY STATUS RESTARTS AGE
pod-demo 2/2 Running 0 43s
[root@k8s-master ~]# kubectl get pods pod-demo -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-demo 2/2 Running 0 4m23s 10.244.1.213 k8s-node1 <none> <none>
[root@k8s-master ~]# kubectl get no -l disktype=ssd
NAME STATUS ROLES AGE VERSION
k8s-node1 Ready <none> 16h v1.14.3
3、pod 状态
Pod运行启动过程。如下截图

存活(Liveness) 探针 - 探测应用是否处于健康状态,如果不健康则删除并重新创建容器. 即在什么情况下重启pod是合适的?
就绪(Readiness) 探针 - 探测应用是否启动完成并且处于正常服务状态,如果不正常则不会接收来自 Kubernetes Service 的流量. 即在什么情况下, 我们应该从服务端点列表删除pod, 使其不再响应请求?
Pod生命周期
状态:
创建pod:
Pod生命周期重要行为
初始化容器
容器探测
liveness
readliness
restartPolicy:
Always, OnFailure, Never. Default to Always.
探针类型有三种:
ExecAction、TCPSocketAction、HTTPGetAction
4、存活探测案例
[root@k8s-master ~]# kubectl explain pod.spec.containers.livenessProbe
[root@k8s-master ~]# kubectl explain pod.spec.containers.livenessProbe.exec
自定义探针,只需要定义其中一个就行。
使用自定义命令探测,开启2个窗口。
[root@k8s-master ~]# kubectl get pod liveness-exec-pod -w
[root@k8s-master ~]# cat /root/yas/liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- image: ikubernetes/myapp:v1
name: liveness-exec-container
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/healthy;sleep 20;rm -f /tmp/healthy;sleep 3600"]
livenessProbe:
exec:
command: ["test","-c","/tmp/healthy"]
initialDelaySeconds: 1
periodSeconds: 3
[root@k8s-master ~]# kubectl create -f /root/yas/liveness-exec.yaml
pod/liveness-exec-pod created
[root@k8s-master ~]# kubectl describe pod liveness-exec-pod 查看报错信息
[root@k8s-master ~]# kubectl get pod liveness-exec-pod -w
NAME READY STATUS RESTARTS AGE
liveness-exec-pod 1/1 Running 1 47s
liveness-exec-pod 1/1 Running 2 88s
liveness-exec-pod 1/1 Running 3 2m11s
liveness-exec-pod 1/1 Running 4 2m53s
liveness-exec-pod 0/1 CrashLoopBackOff 4 3m35s
liveness-exec-pod 1/1 Running 5 4m21s
liveness-exec-pod 1/1 Running 6 5m3s
liveness-exec-pod 0/1 CrashLoopBackOff 6 5m45s
httpGet探针示例:
[root@k8s-master ~]# cat /root/yas/liveness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
namespace: default
spec:
containers:
- image: ikubernetes/myapp:v1
name: liveness-httpget-container
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
[root@k8s-master ~]# kubectl create -f /root/yas/liveness-httpget.yaml
此时验证容器时正常运行的,下面故意将路径修改为不存在路径,如下
调整path: /index/html,该路径不存在,容器无法启动。
====》以上是liveness探针,下面引入Readiness探针,Pod对象启动后,容器应用通常需要一段时间才能完成其初始化过程,例如加载配置或数据,甚至有些程序需要运行某类的预热过程,若在此阶段完成之前接入客户端的请求,势必会因为等待太久而影响用户体验,这时就需要就绪探针。 如果没有将就绪探针添加到pod中,它们几乎会立即成为服务端点,导致服务不可用。
就绪性探测,跟service关联。
新增的对应标签pod启动成功,但是pod内的war代码没有完成启动就绪,项目访问访问出现404.(必须要做)
就行探测,删除文件后容器未退出,只显示未就绪状态。
[root@k8s-master ~]# cat yas/readiness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
spec:
containers:
- image: ikubernetes/myapp:v1
name: readiness-httpget-container
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
[root@k8s-master ~]# kubectl create -f yas/readiness-httpget.yaml
[root@k8s-master ~]# kubectl exec -it readiness-httpget-pod -- /bin/sh
/ # ps -ef
PID USER TIME COMMAND
1 root 0:00 nginx: master process nginx -g daemon off;
5 nginx 0:00 nginx: worker process
6 root 0:00 /bin/sh
10 root 0:00 ps -ef
/ # rm -f /usr/share/nginx/html/index.html
/ # echo "hi">/usr/share/nginx/html/index.html
/ # exit
[root@k8s-master ~]# kubectl get pod readiness-httpget-pod -w
NAME READY STATUS RESTARTS AGE
readiness-httpget-pod 0/1 Running 0 7m16s
生命周期
$ kubectl explain pods.spec.containers.lifecycle.postStart
$ kubectl explain pod.spec.containers.lifecycle.preStop
命令优先级,先是执行pod command,在执行容器生命周期command。
[root@k8s-master ~]# cat yas/pod-start.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-start
namespace: default
spec:
containers:
- image: ikubernetes/myapp:v1
name: pod-start-container
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command: ['mkdir','-p','/data/web/html']
command: ['/bin/sh','-c','sleep 360']
[root@k8s-master ~]# kubectl create -f yas/pod-start.yaml
pod/pod-start created
[root@k8s-master ~]# kubectl get pod pod-start
NAME READY STATUS RESTARTS AGE
pod-start 1/1 Running 0 14s
以上问探测生命周期脚本,下面是查看。
[root@k8s-master ~]# kubectl exec -it pod-start -- /bin/sh
/ # ls /data/web/html/
/ # ps -ef
PID USER TIME COMMAND
1 root 0:00 /bin/sh -c sleep 360
5 root 0:00 sleep 360
9 root 0:00 /bin/sh
16 root 0:00 ps -ef
/ # exit
浙公网安备 33010602011771号