一:定义container的相关元数据。
pod资源:
spec.containers<[jobject]>
- name <string>
- image <string>
imagepullpolicy <string> 这项表示镜像获取的策略,配置好清单时不可修改。
string有三种方式:always(总是),Never(从不), IfNotpresent(如果本地有,就用本地的镜像。)
二:修改镜像的默认应用:command,args
kubernetes中command和docker image中command相互格式用法。
(1)如果kubernetes配置清单中,没有定义command和args,那么就运行image本省command
(2)如果kubernetes配置清单中定义了command没有args,那么image本身的command和entrypoint就没用了,用配置清单中的command
(3)如果配置清单中定义了只有args,那么就将image本身Entrypoint当命令,args当参数,将args传送给entrypoint命令运行,image中的command就没用了
(4)如果配置清单中定义了args和command,那么就运行自己给的
三:pod中标签格式定义。
标签格式:key--->value
key:字母,数字。
value:可以为空,只能字母或数字开头及结尾,中间可使用多种元素。
[root@k8s-master manifests]# kubectl get pods --show-labels 查看各pod的标签
NAME READY STATUS RESTARTS AGE LABELS
myapp-5d587c4d45-5fltt 1/1 Running 1 4d18h app=myapp,pod-template-hash=5d587c4d45
myapp-5d587c4d45-gbb6r 1/1 Running 2 10d app=myapp,pod-template-hash=5d587c4d45
myapp-5d587c4d45-zb86g 1/1 Running 1 4d18h app=myapp,pod-template-hash=5d587c4d45
[root@k8s-master manifests]# kubectl get pods -L app 用来查看指定所有资源类别对应的标签的值
NAME READY STATUS RESTARTS AGE APP
myapp-5d587c4d45-5fltt 1/1 Running 1 4d18h myapp
myapp-5d587c4d45-gbb6r 1/1 Running 2 10d myapp
myapp-5d587c4d45-zb86g 1/1 Running 1 4d18h myapp
[root@k8s-master manifests]# kubectl get pods -L app,run 显示多个标签的值
NAME READY STATUS RESTARTS AGE APP RUN
myapp-5d587c4d45-5fltt 1/1 Running 1 4d18h myapp
myapp-5d587c4d45-gbb6r 1/1 Running 2 10d myapp
myapp-5d587c4d45-zb86g 1/1 Running 1 4d18h myapp
[root@k8s-master manifests]# kubectl label pods pod-demo release=canary 为指定的pod打标签,key为release值为canary
pod/pod-demo labeled
[root@k8s-master manifests]# kubectl label pods pod-demo release=stable 提示标签已存在,使用--overwrite强制打标签
error: 'release' already has a value (canary), and --overwrite is false
[root@k8s-master manifests]# kubectl label pods pod-demo release=stable --overwrite
pod/pod-demo labeled
标签选择器。
(1)等值关系; (2)集合关系
例如:等值关系的labels
[root@k8s-master manifests]# kubectl get pods -L release=stable,app=myapp 这表示查看pod中有release=stable 和app=myapp标签的pod。
NAME READY STATUS RESTARTS AGE RELEASE=STABLE APP=MYAPP
myapp-5d587c4d45-5fltt 1/1 Running 1 4d19h
myapp-5d587c4d45-gbb6r 1/1 Running 2 10d
myapp-5d587c4d45-zb86g 1/1 Running 1 4d19h
pod-demo 0/1 CrashLoopBackOff 6 11m
[root@k8s-master manifests]# kubectl get pods -l release!=canary 这表示查找release不等于canary的pod
NAME READY STATUS RESTARTS AGE
myapp-5d587c4d45-5fltt 1/1 Running 1 4d19h
myapp-5d587c4d45-gbb6r 1/1 Running 2 10d
myapp-5d587c4d45-zb86g 1/1 Running 1 4d19h
pod-demo 0/1 CrashLoopBackOff 9 32m
[root@k8s-master manifests]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myapp-5d587c4d45-5fltt 1/1 Running 1 4d19h app=myapp,pod-template-hash=5d587c4d45
myapp-5d587c4d45-gbb6r 1/1 Running 2 10d app=myapp,pod-template-hash=5d587c4d45
myapp-5d587c4d45-zb86g 1/1 Running 1 4d19h app=myapp,pod-template-hash=5d587c4d45
pod-demo 0/1 CrashLoopBackOff 9 32m app=myapp,release=stable
集合关系。
key in (value,value2....) key存在
key notin (value,value2....) key不存在
[root@k8s-master manifests]# kubectl get pods -l "release in (canary,beta,alpha,stable)"这表示那个pod中的健release是canary beta alpha stable
NAME READY STATUS RESTARTS AGE
pod-demo 0/1 CrashLoopBackOff 11 43m
[root@k8s-master manifests]# kubectl get pods -l "release notin (canary,beta,alpha,stable)" 这表示那个pod中的健release不是canary beta alpha stable
NAME READY STATUS RESTARTS AGE
myapp-5d587c4d45-5fltt 1/1 Running 1 4d19h
myapp-5d587c4d45-gbb6r 1/1 Running 2 10d
myapp-5d587c4d45-zb86g 1/1 Running 1 4d19h
许多资源支持内嵌字段,其使用的标签选择器。
matchLabels:直接给定键值
matchExpressions:基于给定的表达式来定义使用标签选择器{key: "KEY"],operator:"OPERATOR",values:[val1,val2]
操作符:
in,Notin:value字段的值必须为非空列表
Exists,NotExists:volues字段的值必须为空列表
nodeselector <map[string]string> :这项表示节点选择器。
nodeName <string>:直接指定运行在那个节点上
annotations(资源注解):与label不同的地方在于,他不能用于挑选资源对象,仅用于为对象提供元数据
例如:我们为节点k8s-node1打上标签
[root@k8s-master manifests]# kubectl label nodes k8s-node1 disktype=ssd
node/k8s-node1 labeled
[root@k8s-master manifests]# kubect get nodes --show-labels
-bash: kubect: command not found
[root@k8s-master manifests]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
k8s-master Ready master 21d v1.18.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> 21d v1.18.5 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> 16d v1.18.5 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 manifests]#
pod的生命周期。
(1)pod的相关状态。
挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
(2)pod生命周期的行为;
初始化容器
容器探测:liveness(存活性检测)readiness(主进程就绪探测)
pod启动前的行为:
initc(初始化容器)----->启动容器前钩子----->liveness probe存活性检测几秒进行----->readiness probe主进程就绪探测---->man container(启动主容器)----->pre stop容器结束后清理工作,用户命令钩子结束后钩子。
(1)例如创建一个pod实列:
[root@k8s-master manifests]# vim pod-demo.yaml
apiVersion: v1 #表示我们创建的资源属于哪个资源群组,通过kubectl api-versions
kind: Pod #表示我们创建的资源对象。
metadata: #这表示我们创建资源的元数据。
name: pod-demo #创建pod的名称
namespace: default #名称空间为默认
labels: #设置pod资源所带的卷标。
app: myapp
tier: frontend
annotations: #创建资源的作者。
name: Mr_yan
spec: #pod中的对象。
containers: #创建的容器信息
- name: myapp #创建的容器名称
image: ikubernetes/myapp:v1 #依据的创建的镜像。
ports: #监听的端口。
- name: httpd #监听的端口服务名称。 这里所暴露的端口不是真正的暴露,只是做描述而已。
containerPort: 80
- name: https
containerPort: 443
- name: busybox #一个pod中运行一个容器。
image: busybox:latest
imagePullPolicy: IfNotPresent #镜像获取策略,这表示本地有的话就放在本地。
command: #这表示我们登录到容器中执行的命令
- "/bin/sh"
- "-c"
- "sleep 3600"
nodeSelector: #这是将我们的pod调度到标签为disktype:ssd的node节点,
disktype: ssd
[root@k8s-master manifests]# kubectl create -f pod-demo.yaml 根据我们写的文件来创建pod
pod/pod-demo created
[root@k8s-master manifests]# kubectl get pods -o wide 查看创建pod已经被调度到node1节点上面了
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-5d587c4d45-nms7x 1/1 Running 0 2d17h 10.244.1.9 k8s-node1 <none> <none>
myapp-5d587c4d45-r4rcc 1/1 Running 0 2d17h 10.244.2.12 k8s-node2 <none> <none>
myapp-5d587c4d45-tt6lv 1/1 Running 0 2d17h 10.244.2.11 k8s-node2 <none> <none>
nginx-deployment-bd4bfb877-xs62q 1/1 Running 0 9d 10.244.1.2 k8s-node1 <none> <none>
pod-demo 2/2 Running 0 58m 10.244.1.16 k8s-node1 <none> <none>
[root@k8s-master manifests]# kubectl describe pods pod-demo 查看详细信息。
Name: pod-demo
Namespace: default
Priority: 0
Node: k8s-node1/10.5.100.157
Start Time: Fri, 18 Dec 2020 10:47:55 +0800
Labels: app=myapp
tier=frontend
Annotations: name: Mr_yan
Status: Running
IP: 10.244.1.16
IPs:
IP: 10.244.1.16
Containers:
myapp:
Container ID: docker://9f1ad17bab2f75eaf60c809bacb351cfdee686c7a348c52cd8e5c2c940b3b4b8
Image: ikubernetes/myapp:v1
Image ID: docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
Ports: 80/TCP, 443/TCP
Host Ports: 0/TCP, 0/TCP
State: Running
Started: Fri, 18 Dec 2020 10:47:56 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-rgbt5 (ro)
busybox:
Container ID: docker://db64442c48b3f84e56e5875eb55924af8ea44a0c83f8ace4256b8e2e510975a9
Image: busybox:latest
Image ID: docker-pullable://busybox@sha256:9ddee63a712cea977267342e8750ecbc60d3aab25f04ceacfa795e6fce341793
Port: <none>
Host Port: <none>
Command:
/bin/sh
-c
sleep 3600
State: Running
Started: Fri, 18 Dec 2020 10:47:56 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-rgbt5 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-rgbt5:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-rgbt5
Optional: false
QoS Class: BestEffort
Node-Selectors: disktype=ssd
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/pod-demo to k8s-node1
Normal Created 58m kubelet, k8s-node1 Created container myapp
Normal Started 58m kubelet, k8s-node1 Started container myapp
Normal Pulled 58m kubelet, k8s-node1 Container image "busybox:latest" already present on machine
Normal Created 58m kubelet, k8s-node1 Created container busybox
Normal Started 58m kubelet, k8s-node1 Started container busybox
Normal Pulled 58m kubelet, k8s-node1 Container image "ikubernetes/myapp:v1" already present on machine
Pod应用进阶2:
探针类型分为三种:
Probe 是由 kubelet 对容器执行的定期诊断。 要执行诊断,kubelet 调用由容器实现的 Handler (处理程序)。有三种类型的处理程序:
ExecAction: 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
TCPSocketAction: 对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。
HTTPGetAction: 对容器的 IP 地址上指定端口和路径执行 HTTP Get 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。
针对容器有三种探针:
livenessProbe:指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为 Success。
readinessProbe:指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success。
startupProbe: 指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器,而容器依其 重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success。
存活性探针的使用;
[root@k8s-master ~]# kubectl explain pods.spec.containers 查看container支持的相关字段
[root@k8s-master ~]# kubectl explain pods.spec.containers.livenessProbe 查看存活性探测怎么定义
failureThreshold :表示我们探测几次以为是失败的,默认探测3次
periodSeconds: 表示周期性探测,默认每隔10s探测一次
timeoutSeconds: 表示探测的超时时长,默认是1s
exec: 表示exec探针
initialPelaySeconds: 初始化延迟探测时间,表示多长时间开始探测。
[root@k8s-master ~]# kubectl explain pods.spec.containers.livenessProbe.exec 查看exec探针的用法,通过命令检测容器的存活性。
KIND: Pod
VERSION: v1
RESOURCE: exec <Object>
DESCRIPTION:
One and only one of the following should be specified. Exec specifies the
action to take.
ExecAction describes a "run in container" action.
FIELDS:
command <[]string>
Command is the command line to execute inside the container, the working
directory for the command is root ('/') in the container's filesystem. The
command is simply exec'd, it is not run inside a shell, so traditional
shell instructions ('|', etc) won't work. To use a shell, you need to
explicitly call out to that shell. Exit status of 0 is treated as
live/healthy and non-zero is unhealthy.
实例1:创建一个探针的用法实例发,存活性探针。
[root@k8s-master manifests]# vim liveness_exec.yaml 编辑一个存活性探针例子。
apiVersion: v1
kind: Pod
metadata:
name: liveness
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "touch /tmp/healthy; sleep 30s; rm -rf /tmp/healthy; sleep 3600"]
livenessProbe: 定义存活性探针用法,通过命令来测试pod的存活性。
exec:
command: ["test", "-e", "/tmp/healthy"] 表示检测这个文件是否存在。
initialDelaySeconds: 1 表示初始化探测,等多长时间开始探测
periodSeconds: 3 表示我们每隔3秒进行探测。
[root@k8s-master manifests]# kubectl create -f liveness_exec.yaml
[root@k8s-master manifests]# kubectl get pods -o wide 查看创建的pod liveness
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liveness 0/1 CrashLoopBackOff 44 141m 10.244.2.23 k8s-node2 <none> <none>
myapp-5d587c4d45-nms7x 1/1 Running 1 5d22h 10.244.1.17 k8s-node1 <none> <none>
myapp-5d587c4d45-r4rcc 1/1 Running 1 5d22h 10.244.2.18 k8s-node2 <none> <none>
myapp-5d587c4d45-tt6lv 1/1 Running 1 5d22h 10.244.2.16 k8s-node2 <none> <none>
nginx-deployment-bd4bfb877-xs62q 1/1 Running 1 13d 10.244.1.18 k8s-node1 <none> <none>
pod-demo 2/2 Running 2 167m 10.244.1.21 k8s-node1 <none> <none>
[root@k8s-master manifests]# kubectl describe pods liveness 查看创建的pod详细信息,
在这里做一下描述,因为我们livenessProbe exec探针如果探测失败那么kubelet就会杀死容器,进行重启容器。所以我们的liveness这个pod restarts会有多次。
实例2:创建一个就绪性探针实例,就绪性探针指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址
[root@k8s-master manifests]# vim readiness_exec.yaml 编辑一个yaml文件,创建一个具有就绪性探针的pod
apiVersion: v1
kind: Pod
metadata:
name: readiness
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: httpd
containerPort: 80
readinessProbe: 定义一个就绪性探针,使用httpget请求服务的80端口,如果返回状态码为大于200小于400表示服务健康,如果请求为其他状态码的则为不健康,表示不具备提供服务的
httpGet:
port: http
path: /index.html 请求这个url
initialDelaySeconds: 1
periodSeconds: 3
~
[root@k8s-master manifests]# kubectl create -f readiness_exec.yaml
pod/readiness created
[root@k8s-master manifests]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-5d587c4d45-nms7x 1/1 Running 1 5d23h 10.244.1.17 k8s-node1 <none> <none>
myapp-5d587c4d45-r4rcc 1/1 Running 1 5d23h 10.244.2.18 k8s-node2 <none> <none>
myapp-5d587c4d45-tt6lv 1/1 Running 1 5d23h 10.244.2.16 k8s-node2 <none> <none>
nginx-deployment-bd4bfb877-xs62q 1/1 Running 1 13d 10.244.1.18 k8s-node1 <none> <none>
pod-demo 2/2 Running 3 3h4m 10.244.1.21 k8s-node1 <none> <none>
readiness 0/1 Running 0 8s 10.244.2.30 k8s-node2 <none> <none>
[root@k8s-master manifests]# curl 10.244.2.30 请求pod
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
#我们将nginx提供的主页面删除。
[root@k8s-master manifests]# kubectl exec -it readiness -c myapp -- /bin/sh
/ # ls
bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var
/ # rm -f /usr/share/nginx/html/index.html
[root@k8s-master manifests]# curl 10.244.2.30 再次请求pod,发现pod提供的服务是不健康的。
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html>
#我们将nginx主页面进行恢复。
[root@k8s-master manifests]# kubectl exec -it readiness -c myapp -- /bin/sh
/ # ls
bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var
/ # echo 'hi' > /usr/share/nginx/html/index.html
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 nginx: master process nginx -g daemon off;
6 nginx 0:00 nginx: worker process
7 root 0:00 /bin/sh
14 root 0:00 /bin/sh
20 root 0:00 ps aux
/ # nginx -s reload 重启nginx
2020/12/22 10:19:15 [notice] 24#24: signal process started
/ #
[root@k8s-master manifests]# curl 10.244.2.30 请求服务正常。
hi
就绪性探针也是pod生命周期的一部分。用于检测pod的中主进程是否能够健康提供服务
Pod生命周期中,容器启动前钩子和启动后钩子实例,作用是我们为容器启动前和结束后对容器执行的一些命令。
[root@k8s-master manifests]# kubectl explain pods.spec.containers.lifecycle 查看支持的钩子
[root@k8s-master manifests]# kubectl explain pods.spec.containers.lifecycle.postStart 查看终止前钩子的用法。
[root@k8s-master manifests]# vim postStart.yaml
apiVersion: v1
kind: Pod
metadata:
name: post
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
lifecycle: 定义一个容器终止前钩子。
postStart:
exec: 容器终止前运行的命令
command: ["/bin/sh", "-c", "echo homepaye >> /tmp/index.html"]
~
[root@k8s-master manifests]# kubectl create -f postStart.yaml
pod/post created
[root@k8s-master manifests]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-5d587c4d45-nms7x 1/1 Running 1 6d22h 10.244.1.17 k8s-node1 <none> <none>
myapp-5d587c4d45-r4rcc 1/1 Running 1 6d22h 10.244.2.18 k8s-node2 <none> <none>
myapp-5d587c4d45-tt6lv 1/1 Running 1 6d22h 10.244.2.16 k8s-node2 <none> <none>
nginx-deployment-bd4bfb877-xs62q 1/1 Running 1 13d 10.244.1.18 k8s-node1 <none> <none>
pod-demo 2/2 Running 26 26h 10.244.1.21 k8s-node1 <none> <none>
post 1/1 Running 0 8s 10.244.2.33 k8s-node2 <none> <none>
readiness 0/1 Running 0 23h 10.244.2.30 k8s-node2 <none> <none>
[root@k8s-master manifests]# kubectl exec -it post -c myapp -- /bin/sh 进入容器中查看命令运行情况。
/ # ls
bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var
/ # ls
bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var
/ # cd tmp/
/tmp # ls
index.html
/tmp # cat index.html
homepaye
/tmp #
总结:对于创建一个pod资源,需要(apiversion, kind,metadata,spec,status(只读)
pod创建过程,当我们在配置清单中定义资源时,------>Apiserver---->schlder(调度器)----->调度至目标节点----->启动创建pod资源。