Kubernetes ---- 资源配置清单格式及Label标签、标签选择器、Pod生命周期、Pod存活性探测及就绪型探测
大部分资源的配置清单:
apiVersion: group/version
# 查看所支持的版本.
$ kubectl api-versions
kind: 资源类别(Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob,Service....)
metadata: 元数据
name(同一类别中名称要唯一,不同的namespace中name可以重名)
namespace
labels: 标签,方便控制器及Service进行管理.
annotations: 资源注解
每个的资源的引用PATH:
/api/v1/namespaces/default/pods/client
/组名/版本/名称空间/default的名称空间/pods(资源类型)/资源名称
spec: 定义目标期望的状态,让当前状态像期望状态靠近(副本数量)
status: 当前状态,本字段由kubernetes集群维护,用户无法删除定义.
# 查看Pod的定义规范
$ kubectl explain pod
# 二级字段查询定义规范(查询Pod下的metadata如何定义)
$ kubectl explain pod.metadata
# 查看spec如何定义
$ kubectl explain pod.spec
Pod资源:
spec.containers []<object>
- name <string>
image <string>
imagePullPolicy <string> # 镜像获取策略(Always, Never, IfNotPresent(如果本地不存在就去下载))
如果要覆盖默认的 Entrypoint 与 Cmd,需要遵循如下规则:
1. 如果在容器配置中没有设置command或者args那么将使用Docker镜像自带的命令及其入参。
2. 如果在容器配置中只设置了command但是没有设置args那么容器启动时只会执行该命令,Docker 镜像中自带的命令及其入参会被忽略。
3. 如果在容器配置中只设置了args那么Docker镜像中自带的命令会使用该新入参作为其执行时的入参。
4. 如果在容器配置中同时设置了command与args,那么Docker镜像中自带的命令及其入参会被忽略。容器启动时只会执行配置中设置的命令,并使用配置中设置的入参作为命令的入参。
帮助来源:https://kubernetes.io/zh/docs/tasks/inject-data-application/define-command-argument-container/
args <[]string>
command <[]string>
标签:
# 键值对儿的长度不能超过63个字符
key = value
key: 字母、数字、_、-、.
value: 可以为空,只能以字母或数字开头及结尾,中间可用字母、数字、_、-、.
# 显示pod中标签为app的pod $ kubectl get pods -l app --show-labels # 另外一种绝对性查询,key=value 等值关系: =、==、!= $ kubectl get pods -l app[=|==|!=]myapp --show-labels # 集合关系: KEY in (VALUE1,VALUE2...) KEY not in (VALUE1,VALUE2...) KEY !KEY $ kubectl get pods -l "release in (canary,beta,alpha)" $ kubectl get pods -l "release notin (canary,beta,alpha)" # 给资源对象增加标签 $ kubectl label pod pod-demo release=canary # 修改资源对象的标签 $ kubectl label pod pod-demo release=stable --overwrite # 删除资源对象的标签 $ kubectl label pod pod-demo release-
许多资源支持内嵌字段定义其使用的标签选择器:
matchLabels: 直接给定键值(Service只能用这种)
matchExpressions:基于给定的表达式来定义使用的标签选择器,{key:"KEY",operator:"OPERATOR",values:[VALUE1,VALUE2,VALUE3...]},键与值使用operator定义的格式符进行比较
操作符(operator):
In, NotIn: values字段的值必须为非空列表;
Exists, NotExists: values字段的值必须为空列表;
pod.spec.nodeSelector <map[string]string>
节点标签选择器: 指定Pod运行在哪类节点上(给节点打上标签)
# 给节点增加标签 $ kubectl label node node1 disktype=ssd $ vim pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
# 这里定义了标签,那么Pod只会运行到node1节点上,因为只有node1节点有"disktype=ssd"标签
nodeSelector:
disktype: ssd
pod.spec.nodeName <string>
pod.metadata.annotations:
与label不同的是,不能用于挑选资源对象,仅用于为对象提供"元数据";
metadata:
annotations:
kaikai.com/created-by: "cluster admin"
Pod的生命周期:
1. 初始化容器完成初始化,线性完成;
2. 主容器启动时候,可以做启动后钩子;
3. 主容器结束前,可以做结束前钩子;
4. 可在容器运行过程中做容器探测(liveness probe和readiness probe)支持三中探测行为(1.执行自定义命令;2.像指定的tcp套接字发请求;3.像指定的http服务发请求)
Pod探测:
livenessProbe(存活性探测): 探测主容器是否处于运行状态;
readinessProbe(就绪型探测): 用于判定容器中的主进程是否已经就绪,并可以对外提供服务;
livenessProbe探测中的ExecAction(自定义命令探测):
apiversion: v1 kind: Pod metadata: name: liveness-exec namespace: default spec: containers: - name: liveness-exec-container image: busybox:latest imagePullPolicy: IfNotPresent 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
#注释:
livenessProbe: 对Pod做存活性检测;
exec: 使用存活性检测方法中的ExecAction(自定义命令检测)方法进行检测;
command: 使用哪个命令;
initialDelaySeconds: 当Pod启动1秒后进行检测;
periodSeconds: 执行探测的频率。默认是10秒,此处设为3秒;
$ kubectl describe pod liveness-exec (由于没有做重启策略,所以会不断的重启Pod,Last State的状态还是Terminated,所以Pod有问题,检测验证成功)
livenessProbe探测中的HTTPGetAction(像指定的http服务发请求探测):
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: http containerPort: 80 livenessProbe: httpGet: port: 80 path: /index.html initialDelaySeconds: 1 periodSeconds: 3
#注释:
livenessProbe: 对Pod进行存活性探测
httpGet:采用HttpGetAction方法探测
port: 要探测Pod的哪个端口
path: 请求的URL路径
$ kubectl create -f liveness-httpget.yaml
$ kubectl describe pod liveness-httpget-pod(如下图,没有发现问题)
# 创建问题,发现是否会产生异常
$ kubectl exec -it liveness-httpget-pod -- /bin/sh
/ # rm /usr/share/nginx/html/index.html
键盘同时按住Ctrl + P + Q 不终止容器运行退出容器
$ kubecget describe pod liveness-httpget-pod (会发现已经出现了异常)
readinessProbe(就绪型探测)中的HTTPGetAction(像指定的http服务发请求探测):其他探测方法类似此httpGet方法!
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: http containerPort: 80 readinessProbe: httpGet:
port: 80
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
#注释:
readinessProbe: 使用就绪型探测
httpGet: 就绪型探测中的HTTPGet方法
# 此时查看Pod状态为Running状态,且已经就绪,(READY字段下的第一个1代表已就绪,后边儿的1代表几个容器)
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness-httpget-pod 1/1 Running 0 10s
# 制造问题,验证探测是否有效
$ kubectl exec -it readiness-httpget-pod -- /bin/sh
/ # rm /usr/share/nginx/html/index.html
Ctrl+P+Q不中断容器退出
# 再次查询Pod的状态,发现已经左侧1已经变为0,说明容器此时未就绪;
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness-httpget-pod 0/1 Running 0 32s
# 查看详细信息
$ kubectl describe pod readiness-httpget-pod (ready状态为False,且日志为404;)
# 解决此问题
$ kubectl exec -it readiness-httpget-pod -- /bin/sh
/ # echo "hi" >> /usr/share/nginx/html/index.html
$ kubecget get pods (会发现状态还原了)
NAME READY STATUS RESTARTS AGE
readiness-httpget-pod 1/1 Running 0 14m
Pod启动后操作:
pod.spec.containers.lifecycle.postStart <Object>
apiVersion: v1 kind: Pod metadata: name: poststart-pod namespace: default spec: containers: - name: busybox-httpd image: busybox:latest imagePullPolicy: IfNotPresent lifecycle: postStart: exec: command: ['mkdir','-p','/data/web/html'] command: ['/bin/sh','-c','sleep 3600']
# 注释:
lifecycle: 生命周期(包含了postStart(容器启动后操作)和preStop(容器停止前操作).)
postStart: 容器启动后操作
exec: 当容器启动后,要执行的命令
command: 具体shell
最下面的command: 是容器的命令
注意:postStart要执行的命令必须在容器已经启动了之后才会执行,也就是说最后一个command如果命令无法执行,那么postStart也是无法执行的!
pod.spec.containers.lifecycle.preStop <Object> 与上述类似,不再举例
状态:
- Pending: 挂起,没有节点能够满足调度条件;
- Running: 运行
- Failed: 失败
- Succeeded: 成功
- Unknow: Pod状态是API Server与运行这个Pod的节点上的kubelet通信获取状态信息的,如果kubelet有问题了,那么就有可能unknown;
创建Pod:
1. 将请求提交给API Server;
2. API Server请求的目标状态保存到ETCD中;
3. API Server请求Scheduler进行调度,如果调度成功,则将调度结果保存到ETCD中;
4. 目标节点的kubelet通过API Server当中的状态编号会收到Pod请求,随后kubelet拿到用户创建Pod的清单进行创建启动;
5. 创建成功或失败会有状态,返还给API Server中,再次更新到ETCD中;
restartPolicy:
Always, OnFailure(错误才重启), Never. Default to Always.