资源调度

Label 和 Selector

标签(Label)

配置文件

在各类资源的 metadata.labels 中进行配置
zho

kubectl

1
2
3
4
5
6
7
8
9
10
#临时创建label
kubectl label po <资源名称> app=hello
kubectl label po <资源名称> app=hello2 --overwrite

#修改已经存在的标签
# selector 按照 label 单值查找节点
kubectl get po -A -l app=hello

# 查看所有节点的 labels
kubectl get po --show-labels

选择器(selector)

  • 配置文件:在各对象的配置 spec.selector 或其他可以写 selector 的属性中编写

  • kubectl命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 匹配单个值,查找 app=hello 的 pod
    kubectl get po -A -l app=hello

    # 匹配多个值
    kubectl get po -A -l 'k8s-app in (metrics-server, kubernetes-dashboard)'


    # 查找 version!=1 and app=nginx 的 pod 信息
    kubectl get po -l version!=1,app=nginx

    # 不等值 + 语句
    kubectl get po -A -l version!=1,'app in (busybox, nginx)'

Deployment

功能

  1. 创建

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    创建一个 deployment
    kubectl create deploy nginx-deploy --image=nginx:1.7.9

    或执行
    kubectl create -f xxx.yaml --record
    --record 会在 annotation 中记录当前命令创建或升级了资源,后续可以查看做过哪些变动操作。

    查看部署信息
    kubectl get deployments

    查看 rs
    kubectl get rs

    查看 pod 以及展示标签,可以看到是关联的那个 rs
    kubectl get pods --show-labels
  2. 滚动更新

    只有修改了 deployment 配置文件中的 template 中的属性后,才会触发更新操作

    修改 nginx 版本号

    1
    kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

    或者通过 kubectl edit deployment/nginx-deployment 进行修改

    查看滚动更新的过程

    1
    kubectl rollout status deploy <deployment_name>

    查看部署描述,最后展示发生的事件列表也可以看到滚动更新过程

    1
    kubectl describe deploy <deployment_name>

    通过 kubectl get deployments 获取部署信息,UP-TO-DATE 表示已经有多少副本达到了配置中要求的数目

    通过 kubectl get rs 可以看到增加了一个新的 rs

    通过 kubectl get pods 可以看到所有 pod 关联的 rs 变成了新的

    多个滚动更新并行

    假设当前有 5 个 nginx:1.7.9 版本,你想将版本更新为 1.9.1,当更新成功第三个以后,你马上又将期望更新的版本改为
    1.9.2,那么此时会立马删除之前的三个,并且立马开启更新 1.9.2 的任务

  3. 回滚

    有时候你可能想回退一个Deployment,例如,当Deployment不稳定时,比如一直crash looping。

    默认情况下,kubernetes会在系统中保存前两次的Deployment的rollout历史记录,以便你可以随时会退(你可以修改revision history
    limit来更改保存的revision数)。

    案例:
    更新 deployment 时参数不小心写错,如 nginx:1.9.1 写成了 nginx:1.91

    1
    kubectl set image deployment/nginx-deploy nginx=nginx:1.91

    监控滚动升级状态,由于镜像名称错误,下载镜像失败,因此更新过程会卡住

    1
    kubectl rollout status deployments nginx-deploy

    结束监听后,获取 rs 信息,我们可以看到新增的 rs 副本数是 2 个

    1
    kubectl get rs

    通过 kubectl get pods 获取 pods 信息,我们可以看到关联到新的 rs 的 pod,状态处于 ImagePullBackOff 状态

    为了修复这个问题,我们需要找到需要回退的 revision 进行回退
    通过 kubectl rollout history deployment/nginx-deploy 可以获取 revison 的列表

    通过 kubectl rollout history deployment/nginx-deploy --revision=2 可以查看详细信息

    确认要回退的版本后,可以通过 kubectl rollout undo deployment/nginx-deploy 可以回退到上一个版本

    也可以回退到指定的 revision

    1
    kubectl rollout undo deployment/nginx-deploy --to-revision=2

    再次通过 kubectl get deploymentkubectl describe deployment 可以看到,我们的版本已经回退到对应的 revison 上了

    可以通过设置 .spec.revisonHistoryLimit 来指定 deployment 保留多少 revison,如果设置为 0,则不允许 deployment 回退了。

  4. 扩容缩容

    通过 kube scale 命令可以进行自动扩容/缩容,以及通过 kube edit 编辑 replcas 也可以实现扩容/缩容

    扩容与缩容只是直接创建副本数,没有更新 pod template 因此不会创建新的 rs

  5. 暂停与恢复

    由于每次对 pod template 中的信息发生修改后,都会触发更新 deployment
    操作,那么此时如果频繁修改信息,就会产生多次更新,而实际上只需要执行最后一次更新即可,当出现此类情况时我们就可以暂停
    deployment 的 rollout

    通过 kubectl rollout pause deployment <name> 就可以实现暂停,直到你下次恢复后才会继续进行滚动更新

    尝试对容器进行修改,然后查看是否发生更新操作了

    1
    2
    kubectl set image deploy <name> nginx=nginx:1.17.9
    kubectl get po

配置文件

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
apiVersion: apps/v1 # deployment api 版本
kind: Deployment # 资源类型为 deployment
metadata: # 元信息
labels: # 标签
app: nginx-deploy # 具体的 key: value 配置形式
name: nginx-deploy # deployment 的名字
namespace: default # 所在的命名空间
spec:
replicas: 1 # 期望副本数
revisionHistoryLimit: 10 # 进行滚动更新后,保留的历史版本数
selector: # 选择器,用于找到匹配的 RS
matchLabels: # 按照标签匹配
app: nginx-deploy # 匹配的标签key/value
strategy: # 更新策略
rollingUpdate: # 滚动更新配置
maxSurge: 25% # 进行滚动更新时,更新的个数最多可以超过期望副本数的个数/比例
maxUnavailable: 25% # 进行滚动更新时,最大不可用比例更新比例,表示在所有副本数中,最多可以有多少个不更新成功
type: RollingUpdate # 更新类型,采用滚动更新
template: # pod 模板
metadata: # pod 的元信息
labels: # pod 的标签
app: nginx-deploy
spec: # pod 期望信息
containers: # pod 的容器
- image: nginx:1.7.9 # 镜像
imagePullPolicy: IfNotPresent # 拉取策略
name: nginx # 容器名称
restartPolicy: Always # 重启策略
terminationGracePeriodSeconds: 30 # 删除操作最多宽限多长时间

StatefulSet

功能

  1. 创建

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    kubectl create -f web.yaml

    # 查看 service 和 statefulset => sts
    kubectl get service nginx
    kubectl get statefulset web

    # 查看 PVC 信息
    kubectl get pvc

    # 查看创建的 pod,这些 pod 是有序的
    kubectl get pods -l app=nginx

    # 查看这些 pod 的 dns
    # 运行一个 pod,基础镜像为 busybox 工具包,利用里面的 nslookup 可以看到 dns 信息
    kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
    nslookup web-0.nginx
  2. 扩容缩容

    1
    2
    3
    4
    5
    # 扩容
    $ kubectl scale statefulset web --replicas=5

    # 缩容
    $ kubectl patch statefulset web -p '{"spec":{"replicas":3}}'
  3. 镜像更新

    1
    2
    # 镜像更新(目前还不支持直接更新 image,需要 patch 来间接实现)
    kubectl patch sts web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:1.9.1"}]'
    1. RollingUpdate

      StatefulSet 也可以采用滚动更新策略,同样是修改 pod template 属性后会触发更新,但是由于 pod 是有序的,在 StatefulSet
      中更新时是基于 pod 的顺序倒序更新的

      1. 灰度发布

        利用滚动更新中的 partition 属性,可以实现简易的灰度发布的效果

        例如我们有 5 个 pod,如果当前 partition 设置为 3,那么此时滚动更新时,只会更新那些 序号 >= 3 的 pod

        利用该机制,我们可以通过控制 partition 的值,来决定只更新其中一部分 pod,确认没有问题后再主键增大更新的 pod
        数量,最终实现全部 pod 更新

    2. OnDelete

      只有在 pod 被删除时会进行更新操作

  4. 删除

    1
    2
    3
    4
    5
    6
    7
    # 删除 StatefulSet 和 Headless Service
    # 级联删除:删除 statefulset 时会同时删除 pods
    kubectl delete statefulset web
    # 非级联删除:删除 statefulset 时不会删除 pods,删除 sts 后,pods 就没人管了,此时再删除 pod 不会重建的
    kubectl deelte sts web --cascade=false
    # 删除 service
    kubectl delete service nginx
  5. 删除pvc

    1
    2
    # StatefulSet删除后PVC还会保留着,数据不再使用的话也需要删除
    $ kubectl delete pvc www-web-0 www-web-1

配置文件

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
39
40
41
42
43
44
45
46
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
annotations:
volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi

DaemonSet

配置文件

指定Node节点

滚动更新

HPA 自动扩/缩容

开启指标服务

CPU、内存指标监控

自定义metrics