1. 1. 容器内获取pod信息
  2. 2. Pod生命周期和重启策略
    1. 2.1. 生命周期
    2. 2.2. 重启策略
  3. 3. 健康检查和服务可用性检查
    1. 3.1. LivenessProbe探针
    2. 3.2. ReadinessProbe探针
  4. 4. 调度策略
    1. 4.1. NodeSelector
    2. 4.2. NodeAffinity亲和性调度
    3. 4.3. PodAffinity亲和性调度
    4. 4.4. Taints and Tolerations 污点和容忍
  5. 5. Pod调度
    1. 5.1. RC & Deployment
    2. 5.2. DaemonSet
    3. 5.3. Job
    4. 5.4. Cronjob
  6. 6. Init Container 初始化容器
  7. 7. Pod升级和回滚
    1. 7.1. Deployment 升级和回滚
    2. 7.2. 暂停和恢复Deployment部署
  8. 8. Pod的扩缩容
    1. 8.1. 手动扩缩容机制
  9. 9. ConfigMap
    1. 9.1. 使用场景
    2. 9.2. 定义方式
    3. 9.3. 使用方式
    4. 9.4. ConfigMap的限制条件

容器内获取pod信息

  • 环境变量,将pod信息注入为环境变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    env:
    - name: POD_NAME
    valueFrom:
    fieldRef:
    fieldPath: metadata.name
    - name: POD_NAMESPACE
    valueFrom:
    fieldRef:
    fieldPath: metadata.namespace
  • Volume挂载方式,类似于环境变量,只是将数据保存为文件并挂载到内部

Pod生命周期和重启策略

生命周期

  • Pending 已创建pod,但还其中容器一个容器镜像还没有创建
  • Running Pod内所有容器都创建,且至少有一个容器处于运行状态
  • Successed Pod中所有容器均成功执行并退出,且不会再重启
  • Failed Pod内所有容器都已退出,单至少有一个容器退出为失败状态
  • Unknown 无法获取该Pod的状态

重启策略

  • Always 默认,当容器失效时,kubelet自动重启该容器
  • OnFailure 容器终止运行且退出码不为0,kubelet自动重启该容器
  • Never 无论容器运行状态如何,kubelet都不会重启容器

kubelet重启失效容器的时间间隔以sync-frequency乘以2n,如1,2,4,8倍,最长延时5min,并在成功重启后10min后重置该时间

每种控制器对pod的重启策略要去如下:

  • RC和DaemonSet 必须设置为always,需要保证该容器持续运行
  • Job OnFailure或者Never,确保容器执行完成后不再重启
  • kubelet 在pod失效时自动重启,不论将RestartPolicy设置为什么值,都不会对pod进行健康检查

健康检查和服务可用性检查

LivenessProbe探针

判断容器是否存活,如果探针探测到容器不健康,则会kill掉容器。如果不包含该探针,则该容器的LivenessProbe探针返回值永远是Success

ReadinessProbe探针

判断容器服务是否可用(Ready状态),达到Ready状态的Pod才可以接收请求

  • ExecAction 执行命令
  • TCPSocketAction socket的ip和端口检查
  • HTTPGetAction 调用http get方法状态码大于等于200且小于400,正常
    1
    2
    - initialDelaySeconds 启动容器后进行首次检查的等待时间,单位为s
    - timeoutSeconds 健康检查发送请求后等待响应的超时时间,单位为s

调度策略

NodeSelector

通过node标签和pod的nodeselector属性匹配来定向调到到某个node节点上

NodeAffinity亲和性调度

硬亲和requiredDuringSchedulingIgnoredDuringExecution 必须满足指定的规则才可以调度pod到node上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity
namespace: default
labels:
app: myapp-nodeselector
tier: frontend
annotations:
created-by: "ttxsgoto"
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性
nodeSelectorTerms:
- matchExpressions:
- key: zone
operator: In
values:
- foo
- bar

软亲和preferredDuringSchedulingIgnoredDuringExecution 强调优先满足指定规则,则尝试调到pod到node,但如果没有满足条件,也调度到node,不强制限制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity2
namespace: default
labels:
app: myapp-nodeselector
tier: frontend
annotations:
created-by: "ttxsgoto"
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 软亲和性
- preference:
matchExpressions:
- key: zone
operator: In
values:
- foo
- bar
weight: 60

说明

  1. 如果同时定义了nodeSelector和nodeAffinty,那么必须满足两个条件,pod才能运行在指定的node上
  2. 如果nodeAffinity指定了多个nodeSelectorTerms,那么其中一个能够匹配成功即可
  3. 如果nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有的matchExpressions才能运行该Pod

PodAffinity亲和性调度

根据在节点上正在运行的pod的标签来判断调度,要求对节点和Pod两个条件进行匹配, 第一个pod启动,其他的pod也在该node启动

requiredDuringSchedulingIgnoredDuringExecution 必须满足指定的规则才可以调度pod到node上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
apiVersion: v1
kind: Pod
metadata:
name: pod-first
namespace: default
labels:
app: myapp-nodeselector
tier: frontend
annotations:
created-by: "ttxsgoto"
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
name: pod-second
namespace: default
labels:
app: myapp-db
tier: db
annotations:
created-by: "ttxsgoto"
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["sh", "-c", "sleep 3600"]
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- {key: app, operator: In, values: ["myapp-nodeselector"]}
topologyKey: kubernetes.io/hostname

反亲和性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
apiVersion: v1
kind: Pod
metadata:
name: pod-first
namespace: default
labels:
app: myapp-nodeselector
tier: frontend
annotations:
created-by: "ttxsgoto"
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
name: pod-second
namespace: default
labels:
app: myapp-db
tier: db
annotations:
created-by: "ttxsgoto"
spec:
containers:
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["sh", "-c", "sleep 3600"]
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- {key: app, operator: In, values: ["myapp-nodeselector"]}
topologyKey: kubernetes.io/hostname

Taints and Tolerations 污点和容忍

让Node拒绝Pod的运行,让Pod避开那些不合适的Node,除非pod明确声明能够容忍这些污点,否则无法在这些node上运行

  • NoSchedule 仅影响调度过程,对已启动的Pod对象不产生影响,明确声明可以容忍这个taint,否则就不会调度到该node上
  • PreferNoSchedule 既影响调度过程,也影响现有的Pod对象,意思为优先,没有对应的node可以运行,也可以调度到node, 可以为NoSchedule的软限制
  • NoExecute 即影响调度过程,也影响现在的pod对象,Pod已经在该节点运行,则会被驱逐,如果没有在该节点上运行,则不会再被调度到该节点上
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 设置Node上 Taint信息
kubectl taint nodes node1 key=value:NoSchedule
# pod中声明Toleration
tolerations:
- key: "key"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
或者
tolerations:
- key: "key"
operator: "Exists"
effect: "NoSchedule"
说明:
- 如果不指定operator,默认为Equal
- 空的key配合Exists操作符能够匹配所有的键和值
- 空的effect匹配所有的effect

Pod调度

  • RC & Deployment
  • DaemonSet
  • Job
  • Cronjob

RC & Deployment

自动部署一个容器的多个副本,以及持续监控副本的数量,在集群内始终维持指定的副本数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: apps/v1
#apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
minReadySeconds: 5 # kubernetes在等待设置的时间后才进行升级
strategy:
type: rollingUpdate # 更新策略,滚动更新
rollingUpdate:
maxSurge: 25% # 指定可以超过期望的pod数量的最大百分比,也可以是个数
maxUnavailable: 25% # 指定升级过程中不可用pod的最大数量
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80

常用命令

1
2
3
4
5
6
7
kubectl rollout status deployment/nginx-deployment # 查看状态
kubectl rollout pause deployment <deployment-name> # 暂停升级
kubectl rollout resume deploymnet <deployment-name> # 继续升级
kubectl rollout history deployment <deployment-name> # 查看Deployment的升级历史
kubectl rollout history deploymnet <deployment-name> --revision=n # 查看单个deploy revision的信息
kubectl rollout undo deployment <deployment-name> # 回退到上一个版本
kubectl rollout undo deployment <deployment-name> --to-revision=2 # 回滚到指定版本

DaemonSet

  • 在每个node上都调度一个pod,适用于监控系统,数据采集等资源的采集
  • 新加入的node也同样会自动运行一个pod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: jumpserver-nginx
labels:
app.kubernetes.io/name: nginx
spec:
selector:
matchLabels:
app.kubernetes.io/name: nginx
template:
metadata:
labels:
app.kubernetes.io/name: nginx
spec:
containers:
- name: jms-nginx
image: wojiushixiaobai/jms_nginx:1.5.6
ports:
- containerPort: 80
name: nginx
protocol: TCP
volumeMounts:
- name: static
mountPath: /opt/jumpserver/data/static
- name: media
mountPath: /opt/jumpserver/data/media
volumes:
- name: static
nfs:
path: /data/core/static
server: 192.168.238.100
- name: media
nfs:
path: /data/core/media
server: 192.168.238.100

Job

批处理调度,仅执行一次的任务,保证处理任务的一个或者多个pod成功结束

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: batch/v1
kind: Job
metadata:
name: k8s-job
spec:
template:
spec:
containers:
- name: python
image: python:3.8-alpine
command: ["python", "-c", "import socket; print(socket.gethostbyname(socket.gethostname()))"]
restartPolicy: Never
backoffLimit: 4

Cronjob

  • 在给定时间点只运行一次
  • 周期性地给定时间点运行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: k8s-cronjob
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: python
image: python:3.8-alpine
command: ["python", "-c", "import socket; print(socket.gethostbyname(socket.gethostname()))"]
restartPolicy: OnFailure

Init Container 初始化容器

应用场景

  • 等待其他关联组件正确运行
  • 基于环境变量或者配置模板生成配置文件
  • 从远程数据库中获取本地所需配置,或者自身注册到某个中央数据库中
  • 下载相关依赖包,或者对系统进行一些预配置

init Container和应用容器的区别:

  • 先于应用容器执行,如果设置多个init container,按顺序运行,并且当前一个init container运行成功后,在运行下一个,所有都运行成功后,才会运行应用容器
  • 在init container的定义中也可以设置资源限制,volume的使用
  • 如果多个init container都定义了资源请求,则取最大的值作为所有init container的资源请求值/资源限制值
  • 调度算法将基于pod的有效资源请求值/资源限制值进行计算
  • init container不能设置readinessProbe探针
1
2
3
4
5
6
7
initContainers:
- name: install
image: busybox
command:
- "sh"
- "-c"
- "ls"

Pod升级和回滚

Deployment 升级和回滚

  • deployment升级镜像
1
2
3
4
5
6
7
8
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
或者
kubectl edit deployment/nginx-deployment
# 查看升级状态
kubectl rollout status deployment/nginx-deployment
# 查看rs状态
kubectl get rs

更新策略说明:

  • 在deployment的定义中,可以通过spec.strategy指定pod更新策略,重建(Recreate)和滚动更新(RollingUpdate),默认为RollingUpdate
  • spec.strategy.rollingUpdate.maxUnavilable 指定deployment在更新过程中不可用状态的Pod数量的上限
  • spec.strategy.rollingUpdate.maxSurge 指定在deployment更新pod的过程中pod总数超过pod期望副本数部分的最大值
1
2
3
4
5
6
7
# 查看deployment部署记录
kubectl rollout history deployment/nginx-deployment
# 回滚到上一个部署版本
kubectl rollout undo deployment/nginx-deployment
或者
kubectl rollout undo deployment/nginx-deployment --to-revision=2 # 回滚到之前稳定版本

暂停和恢复Deployment部署

复杂的deployment配置修改,可以先暂停deployment的更新操作,然后进行配置修改,在恢复deployment,一次性触发完整的更新操作

1
2
3
4
5
# 暂停deployment更新操作
kubectl rollout pause deployment/nginx-deployment
# 修改更新操作
# 恢复deployment更新
kubectl rollout resume deploy nginx-deployment

Pod的扩缩容

手动扩缩容机制

1
kubectl scale deployment nginx-deployment --replicas=5

ConfigMap

使用场景

  • 通过环境变量获取configmp的内容
  • 通过volume挂载的方式将configmap中的内容挂载为容器内部的文件或目录
  • 设置容器启动命令的启动参数(引用环境变量)

定义方式

  • yaml配置文件

    1
    2
    3
    4
    5
    6
    7
    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: cm-demo
    data:
    loglevel: info
    datadir: /data/www
  • 通过命令行方式创建

    1
    2
    3
    4
    # 直接指定k-v
    kubectl create configmap NAME --from-literal=key=value
    # 通过目录/文件创建
    kubectl create config NAME --from-file=config-dir or config-file

使用方式

  • 环境变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    env:
    - name: LOGLEVEL
    valueFrom:
    configMapRef
    name: cm-demo
    key: loglevel
    或者
    envFrom:
    - configMapRef
    name: cm-demo # 根据cm-demo中的kv自动生成环境变量
  • volumeMount使用ConfigMap

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    volumeMounts:
    - name: configpath
    mountPath: /data/config
    volumes:
    - name: configpath
    configMap:
    # 如果不指定items,则每个item都会生成一个文件名为key的文件
    name: cm-demo
    items:
    - key: serverxml
    path: server.xml

ConfigMap的限制条件

  • configmap必须在pod之前创建
  • configmap在相同的namespace中的pod使用
  • configmap中的配额管理还未实现
  • 通过–manifest-url或者–config创建的静态pod无法使用configmap
  • configmap挂载操作,在容器中只能挂载为目录,不能为文件