[toc]

Controller控制器的概述

Controller控制器作用

  • pod类型的资源,删除pod后,不会重建
  • 替用户监视并保证相应的节点上始终有用户所期望的副本数量的pod在运行
  • 如果所运行的pod副本数超过了用户期望的,那么控制器就会删掉,直到和用户期望的一致
  • 如果所运行的pod副本数低于用户期望的,那么控制器就会创建,直到和用户期望的一致

Controller控制器类型

  • 不常用
    • RC:Replication Controller
      • 控制Pod起多个副本
    • StatefulSet
      • 有状态的应用,为Pod提供唯一标识,它可以保证部署和scale的顺序
  • 重点且常用
    • RS:ReplicaSet
      • 控制Pod起多个副本,服务挂了自动启动,始终保持相应数量副本
    • Deployment:
      1. Deployment通过控制RS来保证POD始终保持相应的数量副本 // deployment不能直接控制POD,而是控制RS控制器
      2. 支持滚动更新,回滚,回滚默认保留10个版本 // 支持版本更新
      3. 提供声明式配置,支持动态修改 // 支持动态修改
      4. 管理无状态应用最理想的控制器
      5. node节点可能会运行0个或多个POD
    • daemonset
      • 保证每个node节点,有且只有一个POD启动
      • 每台只起一个客户端软件

image-20230613201940281

RS控制器

在资源清单配置RS控制器的方法

  • 正确写法解析

    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
    47
    48
    49
    # 编辑资源清单
    vim nginx-rs.yaml
    apiVersion: apps/v1
    kind: ReplicaSet
    # RS控制器的metadata
    metadata:
    # RS控制器的名字
    name: rs
    spec:
    # 副本数量
    replicas: 5
    selector:
    # 指定要控制的pod标签
    matchLabels:
    name: hcl
    ########### POD ############
    template:
    # POD的metadata
    metadata:
    # POD名字
    name: nginx-pod
    # POD标签名
    labels:
    name: hcl
    spec:
    containers:
    - name: nginx-container
    image: nginx:alpine
    imagePullPolicy: IfNotPresent

    apiVersion: apps/v1
    kind: ReplicaSet
    metadata:
    name: nginx-rs
    spec:
    replicas: 5
    selector:
    matchLabels:
    name: hcl
    template:
    metadata:
    name: nginx-pod
    labels:
    name: hcl
    spec:
    containers:
    - name: nginx-container
    image: nginx:alpine
    imagePullPolicy: IfNotPresent
  • 总结

    1. RS控制器的接口版本不是”v1”,而是”apps/v1”
    2. RS控制器spec中,selector(标签选择器,必须要写)
    3. POD必须使用labels打标签
    4. RS控制器的template要包住原来的POD资源内容

查看启动的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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 查看pod信息
kubectl get pod
NAME READY STATUS RESTARTS AGE
rs-7bv2d 1/1 Running 0 9h
rs-7p94d 1/1 Running 0 9h
rs-fvm4d 1/1 Running 0 9h
rs-tdpqk 1/1 Running 0 9h
rs-tx64q 1/1 Running 0 9h

# 查看pod详细信息
kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
rs-7bv2d 1/1 Running 0 9h 10.2.2.4 k8s03 <none> <none>
rs-7p94d 1/1 Running 0 9h 10.2.1.10 k8s02 <none> <none>
rs-fvm4d 1/1 Running 0 9h 10.2.1.8 k8s02 <none> <none>
rs-tdpqk 1/1 Running 0 9h 10.2.1.9 k8s02 <none> <none>
rs-tx64q 1/1 Running 0 9h 10.2.2.5 k8s03 <none> <none>

# 查看pod标签
kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
rs-7bv2d 1/1 Running 0 9h name=hcl
rs-7p94d 1/1 Running 0 9h name=hcl
rs-fvm4d 1/1 Running 0 9h name=hcl
rs-tdpqk 1/1 Running 0 9h name=hcl
rs-tx64q 1/1 Running 0 9h name=hcl

# 查看RS控制器启动的pod状态
kubectl get rs
NAME DESIRED CURRENT READY AGE
rs 5 5 5 9h

# 查看RS控制器启动的pod详细状态
kubectl describe rs nginx-rs
Name: rs
Namespace: default
Selector: name=hcl
Labels: <none>
Annotations: <none>
Replicas: 5 current / 5 desired
Pods Status: 5 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: name=hcl
Containers:
nginx-container:
Image: nginx:alpine
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Events: <none>

动态扩缩容

1
2
3
4
5
# 通过edit直接修改rs资源清单
kubectl edit rs rs

# 使用scale命令扩缩容
kubectl scale rs rs --replicas=6

Deployment控制器

Deployment控制器 与 RS控制器的关系

虽然我们创建的是Deployment类型资源,但实际上控制副本还是由RS来控制的,Deployment只是替我们去创建RS控制器,然后再由RS去控制POD副本.

Deployment控制器还有一个比较重要的功能就是滚动更新和版本回滚,而这个功能就是以来RS控制器。

image-20230613205228212

Deployment控制器资源清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 正确写法示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dp
spec:
replicas: 5
selector:
matchLabels:
name: hcl
template:
metadata:
name: nginx-pod
labels:
name: hcl
spec:
containers:
- name: nginx-container
image: nginx:alpine
imagePullPolicy: IfNotPresent

查看启动的资源信息

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
47
# 查看资源
kubectl get pod
NAME READY STATUS RESTARTS AGE

nginx-dp-8545cf5fb-46nj7 1/1 Running 0 8s
nginx-dp-8545cf5fb-ghdm4 1/1 Running 0 8s
nginx-dp-8545cf5fb-mxd5z 1/1 Running 0 8s
nginx-dp-8545cf5fb-sl62g 1/1 Running 0 8s
nginx-dp-8545cf5fb-zwjdh 1/1 Running 0 8s

# 查看RS控制器
kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-dp-8545cf5fb 5 5 5 15s

# rs详细信息中的控制器
kubectl describe rs nginx-dp-8545cf5fb
Name: nginx-dp-8545cf5fb
Namespace: default
Selector: name=hcl,pod-template-hash=8545cf5fb
Labels: name=hcl
pod-template-hash=8545cf5fb
Annotations: deployment.kubernetes.io/desired-replicas: 5
deployment.kubernetes.io/max-replicas: 7
deployment.kubernetes.io/revision: 1
Controlled By: Deployment/nginx-dp

# 查看pod详细信息中的控制器
kubectl describe pod nginx-dp-8545cf5fb-ghdm4
Name: nginx-dp-8545cf5fb-ghdm4
Namespace: default
Priority: 0
Node: k8s03/10.0.0.13
Start Time: Tue, 13 Jun 2023 21:01:55 +0800
Labels: name=hcl
pod-template-hash=8545cf5fb
Annotations: <none>
Status: Running
IP: 10.2.2.6
IPs:
IP: 10.2.2.6
Controlled By: ReplicaSet/nginx-dp-8545cf5fb

# 查看deployment控制器
kubectl get deploy 或者 kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-dp 5/5 5 5 4m32s

动态修改deployment资源

  • 修改资源清单更新资源

    • 指定资源清单进行编辑

      1
      kubectl edit -f nginx-dp.yaml
  • 命令行更新资源

    • 根据资源清单更新镜像

      1
      2
      kubectl set image -f nginx-dp.yaml nginx-container=nginx:1.21.3
      deployment.apps/nginx-dp image updated
    • 不指定资源清单更新镜像

      1
      2
      kubectl set image deployment nginx-dp nginx-container=nginx:1.21.4
      deployment.apps/nginx-dp image updated

deployment控制器版本回滚

  • 回滚到上一个版本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    # 查看当前dp镜像版本
    kubectl describe deployments.apps nginx-dp
    Containers:
    nginx-container:
    Image: nginx:1.21.4

    # 查看rs当前记录的各个版本(最多十个)
    kubectl get rs -o wide
    NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
    nginx-dp-54ffb76795 5 5 5 4m25s nginx-container nginx:1.21.4 name=hcl,pod-template-hash=54ffb76795
    nginx-dp-748cdc54f4 0 0 0 8m42s nginx-container nginx:1.21.3 name=hcl,pod-template-hash=748cdc54f4
    nginx-dp-8545cf5fb 0 0 0 23m nginx-container nginx:alpine name=hcl,pod-template-hash=8545cf5fb

    # 回滚
    kubectl rollout undo deployment nginx-dp
    deployment.apps/nginx-dp rolled back

    # 查看是否退回上一个版本
    kubectl get rs -o wide
    NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
    nginx-dp-54ffb76795 0 0 0 7m4s nginx-container nginx:1.21.4 name=hcl,pod-template-hash=54ffb76795
    nginx-dp-748cdc54f4 5 5 5 11m nginx-container nginx:1.21.3 name=hcl,pod-template-hash=748cdc54f4
    nginx-dp-8545cf5fb 0 0 0 25m nginx-container nginx:alpine name=hcl,pod-template-hash=8545cf5fb
  • deployment回滚到指定版本

    • 查看版本

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      # 查看dp所有的历史版本
      kubectl rollout history deployment nginx-dp
      deployment.apps/nginx-dp
      REVISION CHANGE-CAUSE
      1 <none>
      3 <none>
      4 <none>

      # 查看指定revision版本
      kubectl rollout history deployment nginx-dp --revision=5
      deployment.apps/nginx-dp with revision #5
      Pod Template:
      Labels: name=hcl
      pod-template-hash=54ffb76795
      Containers:
      nginx-container:
      Image: nginx:1.21.4
      Port: <none>
      Host Port: <none>
      Environment: <none>
      Mounts: <none>
      Volumes: <none>
    • 回滚

      1
      2
      3
      # 回滚到指定版本
      kubectl rollout undo deployment nginx-dp --to-revision=3
      deployment.apps/nginx-dp rolled back
    • 记录版本更改信息

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      # apply时加上--record
      kubectl apply -f nginx-dp.yaml --record

      # 修改镜像版本时,加上--record
      kubectl set image deployment nginx-dp nginx-container=nginx:1.21.5 --record
      ## 查看dp所有的历史版本
      deployment.apps/nginx-dp
      REVISION CHANGE-CAUSE
      1 <none>
      4 <none>
      5 <none>
      6 kubectl apply --filename=nginx-dp.yaml --record=true
      7 kubectl set image deployment nginx-dp nginx-container=nginx:1.21.5 --record=true

deployment扩缩容

1
2
3
# 修改启动pod数量
kubectl scale deployment nginx-dp --replicas=3
deployment.apps/nginx-dp scaled

DaemonSet控制器

结构图示

image-20230613213855149

概述

  • 简单来说就是每个节点部署一个POD副本
  • 常见的应用场景:
    • 监控容器
    • 日志收集容器

DaemonSet控制器资源清单

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
# 正确语法示例
vim nginx-ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: db-dp
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
name: db-pod
labels:
app: mysql
spec:
containers:
- name: nginx-container
image: mysql:5.7
imagePullPolicy: IfNotPresent

# 应用资源清单
kubectl apply -f nginx-ds.yaml
daemonset.apps/db-dp created

# 查看pod启动列表
kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP
NODE NOMINATED NODE READINESS GATES
db-dp-29chj 0/1 CrashLoopBackOff 2 42s 10.2.1.42
k8s03 <none> <none>
db-dp-h97sh 0/1 CrashLoopBackOff 2 42s 10.2.2.83
k8s02 <none> <none>

HPA自动扩缩容

HPA工作原理

HAP通过收集来的监控指标分析所有Pod的负载情况,并且根据我们设定好的标准来自动扩容收缩RC、 Deployment、RS 或 StatefulSet 中的 Pod 数量

  1. 需要一个 Metric Server 收集所有POD负载情况
  2. 必须使用除了DaemonSet以外的控制器

Metrics Server介绍

在HAP早期版本使用的是一个叫Heapster组件来提供CPU和内存指标的,在后期的版本k8s转向了使用Metrcis Server组件来提供Pod的CPU和内存指标,Metrcis Server通过Metrics API将数据暴露出来,然后我们就可以使用k8s的API来获取相应的数据。

image-20230614161116935

部署Metric Server

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
# 下载yaml文件
wget https://github.com/kubernetes-sigs/metricsserver/releases/download/v0.4.0/components.yaml

# 修改yaml文件(直接apply yaml文件会报错)
## 镜像无法拉取
- 下载镜像,导入到所有Node节点
docker load < metrics-server.tar
## Deployment控制器,每一台node都要起,使用DaemonSet
"kind: Deployment"改为"kind: DaemonSet"
## 跳过证书检查,如果不跳过,就绪性探针无法正常检测,POD虽然是running但是永远0/1
args:
- - --kubelet-insecure-tls
## 启动MetricServer的POD必须跟宿主机共享网络,使用docker的host网络模式
spec:
hostNetwork: true
containers:
- name: xxx
...

# 应用yaml文件
kubectl apply -f components.yaml

# 查看POD状态
kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
metrics-server-qlfnj 1/1 Running 0 7h16m
metrics-server-vkbzj 1/1 Running 0 7h16m

# 测试命令
kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s01 54m 5% 1470Mi 38%
k8s02 30m 3% 713Mi 18%
k8s03 29m 2% 497Mi 57%

生成一个php-apache镜像

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 准备php代码
vim index.php
<?php
$x = 0.0001;
for ($i = 0; $i <= 1000000; $i++) {
$x += sqrt($x);
}
echo "OK!";
?>

# 编写dockerfile构建镜像
vim dockerfile
FROM php:5-apache
ADD index.php /var/www/html/index.php
RUN chmod a+rx index.php

# 构建镜像
docker build -t php:v1 .

# 将镜像导出,发送到所有node上
docker save php:v1 > /tmp/php_v1.tgz
scp /tmp/php_v1.tgz 172.16.1.12:/tmp
scp /tmp/php_v1.tgz 172.16.1.13:/tmp

# node节点导入php镜像
docker load < /tmp/php_v1.tgz
docker load < /tmp/php_v1.tgz

# 启动一个Deployment资源
vim php-apache.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
spec:
replicas: 1
selector:
matchLabels:
run: php-apache
template:
metadata:
labels:
run: php-apache
spec:
containers:
- image: php:v1
imagePullPolicy: IfNotPresent
name: php-apache
ports:
- containerPort: 80
protocol: TCP
resources:
requests:
cpu: 50m

# 启动资源
kubectl apply -f php-apache.yaml

# 查看资源
kubectl get pod -o wide

创建HPA资源

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
# 准备资源清单
vim hpa.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
namespace: default
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
targetCPUUtilizationPercentage: 50

# 应用资源清单
kubectl apply -f hpa.yaml
horizontalpodautoscaler.autoscaling/php-apache created

# 查看HPA资源状态
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 2%/50% 1 10 1 17s

# 压测循环脚本
while true; do wget -q -O- http://IP; done

## 当cpu核心资源达到指定目标后会创建新的pod以分担压力