一. Yaml资源清单
1. YAML 概述
K8S集群中对资源管理和资源对象编排部署都可以通过声明样式(YAML)文件来解决,我们把这种文件叫做资源文件清单
语法格式:
- 通过缩进表示层级关系
- 不能使用Tab进行缩进,只能使用空格,一般缩进2个空格
- 字符后缩进一个空格,比如: 冒号,逗号后面
- 使用---表示新的yaml段开始
- 使用#注释
2. K8S中的资源
1. 命名空间: 仅在此空间有效。K8S中所有内容都抽象为资源,资源实例化之后,叫做对象
- 工作负载型资源: Pod, ReplicaSet, Deployment, StatefulSet, DaemonSet, Jobs...
- 服务发现及负载均衡型资源: Service, Ingress, LoadBalance...
- 配置与存储型资源: Volume(存储卷)...
- 特殊类型的存储卷: ConfigMap(配置中心), Secret(加密数据)...
2. 集群级别: 全集群可见。Namespace, Node, Role, ClusterRole, RoleBinding, ClusterRoleBinding
3. 元数据型: 指标。NPA, PodTemplate, LomitRange
3. 常用字段
1. 版本元数据规格
参数名 | 类型 | 描述 |
apiVersion | String | K8S Api 版本 |
kind | String | 指定创建资源的Controller类型和角色 |
matadata | Object | 元数据对象 |
matadata.name | String | 元数据对象的名字 |
matadata.namespace | String | 指定命名空间 |
spec | Object | 详细定义资源的规格 |
spec.containers[] | List | 定义容器的列表 |
spec.containers[].name | String | 定义容器的名字 |
spec.containers[].image | String | 定义镜像名称 |
2. 镜像拉取策略
参数名 | 类型 | 描述 |
spec.containers[].imagePullPolicy | String | 定义镜像拉取的策略, 默认是IfNotPresent 1. Always: 意思是每次都尝试拉取镜像 2. Never: 表示仅使用本地镜像 3. ifNotPresent: 如果本地有就使用本地,没有在拉取 |
3. 容器资源限制
参数名 | 类型 | 描述 |
spec.containers[].resources | Object | 指定资源限制和资源请求的值 |
spec.containers[].resources.limits | Object | 设置容器运行时资源的运行上限 |
spec.containers[].resources.limits.cpu | String | 指定CPU的限制,单位core数 1c = 1000m |
spec.containers[].resources.limits.memory | String | 指定MEM内存的限制,单位为MiB, GiB |
spec.containers[].resources.requests | Object | 指定容器启动和调度时的限制设置 |
spec.containers[].resources.requests.cpu | String | CPU请求, 单位为core数, 容器启动时初始化可以数量 |
spec.containers[].resources.requests.memory | String | 内存请求, 单位为MiB, GiB. 容器启动的初始化可以数量 |
4. 数据卷挂载
参数名 | 类型 | 描述 |
spec.containers[].volumeMounts[] | List | 指定容器内部的存储卷配置 |
spec.containers[].volumeMounts[].name | String | 指定存储卷名称 |
spec.containers[].volumeMounts[].mountPath | String | 指定被容器挂载的存储卷的路径 |
spec.containers[].volumeMounts[].readOnly | String | 是否只读,默认是读写 |
5. 容器端口映射
参数名 | 类型 | 描述 |
spec.containers[].ports[] | List | 指定容器需要的端口列表 |
spec.containers[].ports[].name | String | 指定端口名称 |
spec.containers[].ports[].containerPort | String | 指定容器需要监听的端口号 |
spec.containers[].ports[].hostPort | String | 指定容器所在主机需要监听的端口号,默认跟containerPort相同,注意设置了hostPort同一台主机无法启动相同副本 |
spec.containers[].ports[].protocol | String | 指定端口协议,支持TCP和UDP,默认值为TCP |
6. 容器环境变量
参数名 | 类型 | 描述 |
spec.containers[].evn[] | List | 环境变量列表 |
spec.containers[].evn[].name | String | 指定环境变量名称 |
spec.containers[].evn[].value | String | 指定环境变量值 |
7. 容器启动命令
参数名 | 类型 | 描述 |
spec.containers[].command[] | List | 指定容器启动命令,可以指定多个 |
spec.containers[].args[] | List | 指定容器启动命令参数 |
spec.containers[].workingDir | String | 指定容器的工作目录 |
8. Pod重启策略
参数名 | 字段类型 | 描述 |
spec.restartPolicy | String | 定义Pod的重启策略, 可选值为Always, OnFailure 默认值为Always 1. Always: Pod一旦终止运行, 则无论容器时如何终止的, kubelet 服务都将重启 2. OnFailure: 只有Pod以非0退出码终止才会重启 3. Never: Pod 终止后,kubelet将退出码报告给Master,不会重启该Pod |
spec.nodeSelector | Object | 定义Node的Label过滤标签 |
spec.imagePullSecrets | Object | 定义pull镜像时, 使用的secret名称 |
spec.hostNetwork | Boolean | 定义是否使用主机网络模式,默认值false |
# 控制器定义
apiVersion: apps/v1 # API版本
kind: Deployment # 资源类型
metadata: # 元数据
name: nginx-deployment
namespace: default
spec: # 资源规格
replicas: 3 # 副本数量
selector: # 标签选择
matchLabels:
app: nginx
# 被控制对象
template: # Pod模版
metadata: # Pod元数据
labels:
app: nginx
spec: # Pod规格
containers: # 容器配置
- name: nginx
image: nginx:latest
ports:
- containerPort: 80 快速编写
# kubectl create 试运行生成
kubectl create deployment web --image=nginx -o yaml --dry-run > nginx.yml
# kubectl get 导出运行的Pod
kubectl get deploy nginx-deployment -o=yaml > nginx-deployment.yml二. Pod
1. Pod 创建时序图
1. 创建指令发送至ApiServer,由ApiServer写入etcd
2. Scheduler监听到有新的Pod创建,根据算法分配node节点,绑定Pod。返回结果由ApiServer写入etcd
3. Kubelet 监听到被分配的Pod,运行docker 运行容器。更新状态返回ApiServer写入etcd
2. Pod 调度策略
1. Pod的资源限制
- 在调度过程中根据resources.request的限制找到能够满足的节点调度
2. 节点选择器: nodeSelector
# 节点添加标签
kubectl label node node1 env_role=prod
# 查看节点标签
kubectl get nodes node1 --show-labels3. 节点亲和性: nodeAffinity,和nodeSelector基本一样,根据节点标签的约束来对Pod调度
- 硬亲和性: 约束条件必须满足
- 软亲和性: 尝试满足
4. 污点和污点容忍
Taint污点: 节点不做普通分配调度,是节点属性
- NoSchedule: 一定不被调度
- PreferNoSchedule: 尽量不被调用
- NoExecute: 不会调度,并且还会驱逐已有的Pod
3. Pod 生命周期

Pod能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的Init容器
1. 运行pause基础容器
2. init Container 初始化容器运行(init C可以有多个,串行运行)
- Init 容器总是运行到成功完成为止,如果Init容器失败,K8S会不断的重启该Pod,直到Init 容器成功为止。如果Pod对应的restartPolicy为Never,则不会重新启动
- 每个Init容器都必须在下一个Init容器启动之前完成
3. main Container 主容器运行(可以有多个)
- start: 在容器启动时,执行一条命令或脚本
- liveness: 存活检测。主要用来确定是否重启容器
- readless: 就绪检测。只有当Pod中所有容器都处于就绪状态,才会作为Service的后端
- stop: 在容器关闭时,执行一条命令或脚本
1. init C 示例
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
initContainers:
- name: init-myservice
image: busybox:1.32.0
# until: 返回非0, 则进入循环. 返回0则退出循环
command: ["sh", "-c", "until nslookup myservice;do echo 'waiting for myservice';sleep 2;done;"]
- name: init-mydb
image: busybox:1.32.0
command: ["sh", "-c", "until nslookup mydb;do echo 'waiting for mydb';sleep 2;done;"]
containers:
- name: myapp-container
image: busybox:1.32.0
command: ["sh", "-c", "echo 'The app is running! && sleep 3600'"]- 查看日志(-c 指定pod里的容器)
kubectl logs myapp-pod -c init-myservice
kubectl logs myapp-pod -c init-myservice -f --tail=10apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377 - 在Pod启动过程中,Init容器会按顺序在Pause之后启动,每个容器必须在下一个容器启动之前成功推出
- 如果由于运行时失败退出,它会根据Pod的restartPolicy指定的策略进行重试
- 在所有的Init容器没有成功之前,Pod将不会变成Ready状态
- 如果Pod重启,所有Init容器必须重新执行
- 对Init容器spec的修改被限制在容器image字段,修改其他字段都不会生效。更改Init容器的image字段,等价于重启该Pod
- Init容器具有应用容器的所有字段。除了readiness
- 在Pod中的每个app和Init容器的名称必须唯一
2. 探针
探针是由kubelet 对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的Handler。有三种类型的处理程序:
- ExecAction: 在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功
- TCPSocketAction: 对指定端口上的容器的IP地址进行TCP检查。如果端口打开,则诊断被认为是成功的
- HTTPGetAction: 对指定的端口和路径上的容器的IP地址执行HTTP Get请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的
每次检测都将获取三种结果之一:
- 成功: 容器通过了检测
- 失败: 容器未通过检测
- 未知: 诊断失败,因此不会采取任何行动
探测方式:
- readinessProbe: 检测容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认为Success
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
spec:
containers:
- name: readiness-httpget-container
image: nginx:1.19.3
readinessProbe:
httpGet:
port: 80
path: /index1.html
initialDelaySeconds: 1 # 延时, 启动后多长时间检测
periodSeconds: 3 # 重试kubectl get pod readiness-httpget-pod -w -o wide
kubectl describe pod readiness-httpget-pod
--- output
Readiness probe failed: HTTP probe failed with statuscode: 404
# 进入容器, 如果多个容器需 -c 指定
kubectl exec -it readiness-httpget-pod -- /bin/bash- livenessProbe: 检测容器是否正在运行。如果存活探测失败,则kubelet会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认为Success
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
spec:
containers:
- name: liveness-exec-container
image: busybox:1.32.0
command: ["/bin/sh", "-c", "touch /tmp/live; sleep 60; rm -f /tmp/live;sleep 3600"]
livenessProbe:
exec:
command: ["test", "-e", "/tmp/live"] # test命令检查某个条件是否成立. -e如果文件存在, 则为真
initialDelaySeconds: 1 # 延时, 启动后多长时间检测
periodSeconds: 3 # 重试kubectl get pod liveness-exec-pod -w
--- output
NAME READY STATUS RESTARTS AGE
liveness-exec-pod 1/1 Running 0 71s
liveness-exec-pod 1/1 Running 1 104s3. Start/Stop
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx:1.19.3
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'Hello from the postStart handler' > /tmp/message"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo 'Hello from the preStop handler' > /tmp/message"]4. Pod 运行状态
- Pending: 挂起,Pod已经被K8S系统接受,但是有容器尚未创建
- Running: 运行,Pod 中所有容器已被创建,至少一个容器正在运行,或处于启动或重启状态
- Succeeded: 成功,Pod中所有容器都被成功终止,并且不会在重启
- Failed: 失败,Pod中的所有容器都已经终止,并且至少有一个容器是失败终止
- Unknown: 未知,因为某些原因无法取得Pod的状态
浙公网安备 33010602011771号