练习题-6
# 课后练习题-6
# 理论练习(开放性试题)
涵盖第 8 章的内容。
- k8s 中的控制器 (opens new window)是什么?
- 在 Deployment 的 yaml 配置项中,有哪几个比较重要的字段?
- 当前有一个 Deployment,副本数为
3
,通过标签app=run
来追踪这三个 Pod。如果我将这三个 Pod 的app
标签删除,会发生什么? - 有一个 Deployment 正处于运行状态,在不删除控制器的情况下,我该如何修改它的副本数?有哪几种方式?
- 水平自动扩缩(HPA)有什么用?
- 某个 HPAv2 同时设置了 CPU 和内存阈值,扩展副本数的条件是超过其中一个(CPU 或内存),还是需要同时超过两个(CPU 和内存)?
- 当平均负载降低之后,HPA 会立即减少副本数吗?
答案
- k8s 中的控制器可以追踪一种或多种集群资源,并确保这些资源以预期状态运行。例如,控制器 Deployment 保证某个命名空间中一定有 N 个指定的 Pod。
- 字段
spec.replicas
用于设置副本数,字段spec.template
用于配置 Pod 模板,字段spec.selector.matchLabels
用于绑定标签并追踪 Pod。 - 这三个 Pod 会脱离这个控制器,成为独立的 Pod。而 Deployment 会另外创建三个新的 Pod,以填补副本数的空缺。最终的 Pod 数量为
6
个。 - 三种:
- 使用
kubectl scale
命令和--replicas=
选项 - 使用
kubectl edit
命令 - 更改 yaml 文件,然后使用
kubectl apply -f
命令应用更新
- 使用
- 水平自动扩缩(HPA)可以绑定 Deployment 并监测其 Pod 负载情况,当平均负载升高 / 减少的时候,HPA 会自动扩展 / 缩减控制器的副本数。从而解放管理员的双手。
- 超过其中一个即可。你可以在第 8 章节的第 “4.3.2” 小节中找到实验过程。
- 不会,因为 HPA 有一段防抖期。当平均负载降下来之后,HPA 会等待一段时间(默认
5
分钟),如果平均负载在这段时间内没有再次升高,则 HPA 才会降低副本数。
# 实操练习
涵盖第 8 章及前面部分章节的内容。
- 检查命名空间
ns1
是否存在,如果不存在,则创建它。 - 在命名空间
default
中创建一个 Deployment,要求如下:- 名称为
deploy-default
- 副本数为
3
- Pod 模板的镜像为
nginx
,镜像下载策略为IfNotPresent
- 为 Pod 配置资源限制,CPU 使用上限为
300
个微核心,内存使用上限为400
MiB
- 名称为
- 在命名空间
ns1
中创建一个 Deployment,要求如下:- 名称为
deploy-ns1
- 副本数为
2
- Pod 模板的镜像为
alpine
,镜像下载策略为IfNotPresent
- Pod 在启动时执行命令
echo "Hello Deployment!!!" && sleep 9999999
- 为 Pod 设置标签
k8s=alpine
- Deployment 根据标签
k8s=alpine
来追踪这些 Pod
- 名称为
- 创建一个 HPA,要求如下:
- HPA 名称为
hpa-1
- 该 HPA 绑定到控制器
deploy-default
上 - 最小副本数为
1
,最大副本数为5
- CPU 阈值为
60%
- HPA 名称为
- 修改控制器
deploy-default
的副本数为1
。 - 列出所有命名空间中具有
k8s=alpine
标签的 Pod,并查看这些 Pod 的命令行输出。 - 删除水平自动扩缩
hpa-1
- 创建新的 HPA,要求如下:
- HPA 名称为
hpa-2
- 该 HPA 绑定到控制器
deploy-default
上 - 最小副本数为
2
,最大副本数为6
- CPU 阈值为百分比,是资源上限的
70%
- 内存阈值为绝对数值,是资源上限的一半(即
200
MiB)
- HPA 名称为
- (选做)自行使用压力测试工具,对控制器
deploy-default
进行压力测试,试验 HPA 的有效性。 - 删除所有的控制器和 HPA。
提示
第四题,通过命令行创建 HPA 的时候,可以使用--name
选项来为 HPA 指定名称。
第八题,必需使用 HPA 的 v2 版本。
答案分隔线
答案分隔线
答案分隔线
答案分隔线
答案分隔线
答案分隔线
答案分隔线
答案分隔线
答案分隔线
# 实操练习答案
# 1. 检查命名空间ns1
是否存在,如果不存在,则创建它。
# 列出所有命名空间
kubectl get ns
# 创建命名空间 ns1
kubectl create ns ns1
2
3
4
5
# 2. 控制器deploy-default
在命名空间default
中创建一个 Deployment,要求如下:
+ 名称为deploy-default
+ 副本数为3
+ Pod 模板的镜像为nginx
,镜像下载策略为IfNotPresent
+ 为 Pod 配置资源限制,CPU 使用上限为300
个微核心,内存使用上限为400
MiB
快速生成一个 yaml 文件,然后通过 vim 对其进行编辑:
kubectl create deployment deploy-default --image nginx --dry-run=client -o yaml > deploy-default.yaml
vim deploy-default.yaml
2
3
这是修改前的配置:
# 旧
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: deploy-default
name: deploy-default
spec:
replicas: 1
selector:
matchLabels:
app: deploy-default
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: deploy-default
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
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: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: deploy-default
name: deploy-default
namespace: default # 命名空间
spec:
replicas: 3 # 副本数
selector:
matchLabels:
app: deploy-default
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: deploy-default
spec:
containers:
- image: nginx # 镜像
imagePullPolicy: IfNotPresent # 镜像下载策略
name: nginx
resources: # 资源限制
limits:
cpu: 300m
memory: 400Mi
status: {}
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
创建这个控制器:
kubectl apply -f deploy-default.yaml
kubectl get deployments
2

# 3. 控制器deploy-ns1
在命名空间ns1
中创建一个 Deployment,要求如下:
+ 名称为deploy-ns1
+ 副本数为2
+ Pod 模板的镜像为alpine
,镜像下载策略为IfNotPresent
+ Pod 在启动时执行命令echo "Hello Deployment!!!" && sleep 9999999
+ 为 Pod 设置标签k8s=alpine
+ Deployment 根据标签k8s=alpine
来追踪这些 Pod
快速生成一个 yaml 文件,然后通过 vim 对其进行编辑:
kubectl create deployment deploy-ns1 --image alpine --dry-run=client -o yaml > deploy-ns1.yaml
vim deploy-ns1.yaml
2
3
这是修改前的配置:
# 旧
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: deploy-ns1
name: deploy-ns1
spec:
replicas: 1
selector:
matchLabels:
app: deploy-ns1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: deploy-ns1
spec:
containers:
- image: alpine
name: alpine
resources: {}
status: {}
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: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: deploy-ns1
name: deploy-ns1
namespace: ns1 # 命名空间
spec:
replicas: 2 # 副本数
selector:
matchLabels:
# app: deploy-ns1
k8s: alpine # 追踪标签
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
# app: deploy-ns1
k8s: alpine # Pod标签
spec:
containers:
- image: alpine # 镜像
imagePullPolicy: IfNotPresent # 镜像下载策略
name: alpine
resources: {}
# 这个是启动时命令
command: ['sh', '-c', 'echo "Hello Deployment!!!" && sleep 9999999']
status: {}
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
创建这个控制器:
kubectl apply -f deploy-ns1.yaml
kubectl get deployments -n ns1
# 或者
kubectl get deployments -A
2
3
4
5

# 4. 水平自动扩缩hpa-1
创建一个 HPA,要求如下:
+ HPA 名称为hpa-1
+ 该 HPA 绑定到控制器deploy-default
上
+ 最小副本数为1
,最大副本数为5
+ CPU 阈值为60%
通过命令行创建这个 HPA:
kubectl autoscale deployment deploy-default --name hpa-1 --min=1 --max=5 --cpu-percent=60
当资源监测情况从<unknown>
变为0%
时,说明一切正常。

# 5. 修改控制器deploy-default
的副本数为1
。
# 方式一
kubectl scale deployment deploy-default --replicas=1
# 方式二
kubectl edit deployment deploy-default
# 方式三
vim deploy-default.yaml
kubectl apply -f deploy-default.yaml
2
3
4
5
6
7
8
9
图中采用最简单的方式一。

# 6. 列出所有命名空间中具有k8s=alpine
标签的 Pod,并查看这些 Pod 的命令行输出。
kubectl get pods -A -l k8s=alpine
kubectl logs -n ns1 <名称1>
kubectl logs -n ns1 <名称2>
2
3
4

# 7. 删除水平自动扩缩hpa-1
kubectl delete hpa hpa-1

# 8. 水平自动扩缩hpa-2
创建新的 HPA,要求如下:
+ HPA 名称为hpa-2
+ 该 HPA 绑定到控制器deploy-default
上
+ 最小副本数为2
,最大副本数为6
+ CPU 阈值为百分比,是资源上限的70%
+ 内存阈值为绝对数值,是资源上限的一半(即200
MiB)
生成一个 HPAv1 的 yaml 配置文件,然后使用 vim 对其进行编辑:
kubectl autoscale deployment deploy-default --name hpa-2 --min=2 --max=6 --dry-run=client -o yaml > hpa-2.yaml
vim hpa-2.yaml
2
3
这是修改之前的配置:
# 旧
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
creationTimestamp: null
name: hpa-2
spec:
maxReplicas: 6
minReplicas: 2
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: deploy-default
status:
currentReplicas: 0
desiredReplicas: 0
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
修改后:
- 修改版本号
v1
为v2
- 添加
metrics
(度量指标)字段
# 新
apiVersion: autoscaling/v2 # 版本号
kind: HorizontalPodAutoscaler
metadata:
creationTimestamp: null
name: hpa-2
spec:
maxReplicas: 6
minReplicas: 2
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: deploy-default
metrics: # 度量指标
- type: Resource # 设置 CPU 指标
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource # 设置内存指标
resource:
name: memory
target:
type: AverageValue
averageValue: 200Mi
status:
currentReplicas: 0
desiredReplicas: 0
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
创建这个 HPA:
kubectl apply -f hpa-2.yaml
kubectl get hpa
2
内存数值2482176
的单位是 Byte(字节),2482176 / 1024 = 2424
KiB,2424 / 1024 ≈ 2.3
MiB。

# 9. (选做)自行使用压力测试工具,对控制器deploy-default
进行压力测试,试验 HPA 的有效性。
1、在任意一台 worker 主机下载压力测试工具:
# worker
yum install httpd-tools
2
2、为控制器deploy-default
创建网络服务,并记录其 IP 地址:
# master
kubectl expose deployment deploy-default --port=80 --target-port=80 --type=NodePort
kubectl get service
2
3
IP 地址为10.108.106.65

3、对控制器进行压力测试:
# worker
ab -t 600 -n 1000000 -c 1000 http://10.108.106.65/
2
4、在 master 上查看扩缩情况:
# master
kubectl top pods ; echo ; kubectl get hpa
2
第一次和第二次查看。

第三次和第四次查看,最终副本数为6
个(达到上限)。

# 10. 删除所有的网络服务、HPA 和控制器。
kubectl delete service deploy-default
kubectl delete hpa hpa-2
kubectl delete deployment deploy-default
kubectl delete deployment deploy-ns1 -n ns1
2
3
4
5
6
