每天5分钟玩转Kubernetes | Deployment
Posted COCOgsta
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每天5分钟玩转Kubernetes | Deployment相关的知识,希望对你有一定的参考价值。
书籍来源:cloudman《每天5分钟玩转Kubernetes》
一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持!
5.1 Deployment
前面我们已经了解到,Kubernetes通过各种Controller来管理Pod的生命周期。为了满足不同业务场景,Kubernetes开发了 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job等多种Controller。我们首先学习最常用的Deployment。
5.1.1 运行Deployment
先从例子开始,运行一个Deployment:
[root@k8s-master ~]# cat deployment-nginx.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- image: nginx:1.7.9
name: nginx
ports:
- containerPort: 80
protocol: TCP
[root@k8s-master ~]#
kubectl apply -f deployment-nginx.yaml
上面的命令将部署包含两个副本的Deployment nginx,容器的image为nginx:1.7.9。
下面详细分析Kubernetes都做了些什么工作,如图所示。
在图5-1中,通过kubectl get deployment命令查看nginx的状态,输出显示两个副本正常运行。
接下来我们用kubectl describe deployment了解更详细的信息,如图所示。
大部分内容都是自解释的,我们重点看图中Type,这里告诉我们创建了一个ReplicaSet nginx-7846f8d4d9,Events是 Deployment的日志,记录了ReplicaSet的启动过程。通过上面的分析,也验证了Deployment通过ReplicaSet来管理Pod的事实。接着我们将注意力切换到nginx-7846f8d4d9,执行kubectl describe replicaset,如图所示。
两个副本已经就绪,用kubectl describe replicaset查看详细信息, 如图所示。
Controlled By指明此ReplicaSet是由Deployment nginx创建的。图中底部是两个副本Pod创建的日志。接着我们来看Pod,执行 kubectl get pod,如图所示。
两个副本Pod都处于Running状态,然后用kubectl describe pod查看更详细的信息,如图所示。
[root@k8s-master ~]# kubectl describe pod nginx-7846f8d4d9-6kdw2
Name: nginx-7846f8d4d9-6kdw2
Namespace: default
Priority: 0
Node: k8s-node1/192.168.1.145
Start Time: Sun, 22 May 2022 18:30:17 -0400
Labels: pod-template-hash=7846f8d4d9
run=nginx
Annotations: <none>
Status: Running
IP: 10.244.2.12
IPs:
IP: 10.244.2.12
Controlled By: ReplicaSet/nginx-7846f8d4d9
Containers:
nginx:
Container ID: docker://0c6701e28dcbd277068b156d2645fdd3a0298e2bf0364a07a367318a686b2594
Image: nginx:1.7.9
Image ID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sun, 22 May 2022 18:30:47 -0400
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-47sgv (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-47sgv:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-47sgv
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/nginx-7846f8d4d9-6kdw2 to k8s-node1
Normal Pulling 11m kubelet, k8s-node1 Pulling image "nginx:1.7.9"
Normal Pulled 11m kubelet, k8s-node1 Successfully pulled image "nginx:1.7.9"
Normal Created 11m kubelet, k8s-node1 Created container nginx
Normal Started 11m kubelet, k8s-node1 Started container nginx
[root@k8s-master ~]#
Controlled By指明此Pod是由ReplicaSet nginx-7846f8d4d9创建的。Events记录了Pod的启动过程。如果操作失败(比如image不存在),也能在这里查到原因。
总结一下这个过程中,如图所示。
(1)用户通过kubectl创建Deployment。
(2)Deployment创建ReplicaSet。
(3)ReplicaSet创建Pod。
从图也可以看出,对象的命名方式是“子对象的名字=父对象名字+随机字符串或数字”。
5.1.2 命令vs配置文件
Kubernetes支持两种创建资源的方式:
(1)用kubectl命令直接创建,比如“kubectl run nginx-deployment --image=nginx:1.7.9--replicas=2”(该命令中replicas在新版本以失效),在命令行中通过参数指定资源的属性。
(2)通过配置文件和kubectl apply创建。要完成前面同样的工作,可执行命令“kubectl apply -f nginx.yml”。
资源的属性写在配置文件中,文件格式为YAML。
下面对这两种方式进行比较。
(1)基于命令的方式:
- 简单、直观、快捷,上手快。
- 适合临时测试或实验。
(2)基于配置文件的方式:
- 配置文件描述了What,即应用最终要达到的状态。
- 配置文件提供了创建资源的模板,能够重复部署。
- 可以像管理代码一样管理部署。
- 适合正式的、跨环境的、规模化部署。
- 这种方式要求熟悉配置文件的语法,有一定难度。
后面我们都将采用配置文件的方式,大家需要尽快熟悉和掌握。
kubectl apply不但能够创建Kubernetes资源,也能对资源进行更新,非常方便。不过Kubernets还提供了几个类似的命令,例如kubectl create、kubectl replace、kubectl edit和kubectl patch。
为避免造成不必要的困扰,我们会尽量只使用kubectl apply,此命令已经能够应对百分之九十多的场景,事半功倍。
5.1.3 Deployment配置文件简介
既然要用YAML配置文件部署应用,现在就很有必要了解一下Deployment的配置格式了,其他Controller(比如DaemonSet)非常类似。
以nginx-deployment为例,配置文件如图所示。
① apiVersion是当前配置格式的版本。
② kind是要创建的资源类型,这里是Deployment。
③ metadata是该资源的元数据,name是必需的元数据项。
④ spec部分是该Deployment的规格说明。
⑤ replicas指明副本数量,默认为1。
⑥ template定义Pod的模板,这是配置文件的重要部分。
⑦ metadata定义Pod的元数据,至少要定义一个label。label的key和value可以任意指定。
⑧ spec描述Pod的规格,此部分定义Pod中每一个容器的属性,name和image是必需的。
此nginx.yml是一个最简单的Deployment配置文件,后面我们学习Kubernetes各项功能时会逐步丰富这个文件。
执行kubectl apply -f nginx.yml,如图所示。
部署成功。同样,也可以通过kubectl get查看nginx-deployment的各种资源,如图所示。
Deployment、ReplicaSet、Pod都已经就绪。如果要删除这些资 源,执行kubectl delete deployment nginx-deployment或者kubectl delete -f nginx.yml,如图所示。
5.1.4 伸缩
伸缩是指在线增加或减少Pod的副本数。
Deployment nginx-deployment初始是两个副本,如图所示。
k8s-node1和k8s-node2上各跑了一个副本。现在修改nginx.yml文件,将副本改成5个,如图所示。
再次执行kubectl apply,如图所示。
三个新副本被创建并调度到k8s-node1和k8s-node2上。
出于安全考虑,默认配置下Kubernetes不会将Pod调度到Master节点。如果希望将k8s-master也当作Node使用,可以执行如下命令:
kubectl taint node k8s-master node-role.kubernetes.io/master-
如果要恢复Master Only状态,执行如下命令:
kubectl taint node k8s-master node-role.kubernetes.io/master=true:NoSchedule
接下来修改配置文件,将副本数减少为3个,重新执行kubectl apply,如图所示。
可以看到两个副本被删除,最终保留了3个副本。
5.1.5 Failover
下面我们模拟k8s-node2故障,关闭该节点,如图所示。(实测halt时,pod一直处于running状态,关掉node所在的虚机才会标注为Terminating状态)
等待一段时间,Kubernetes会检查到k8s-node2不可用,将k8s-node2上的Pod标记为Unknown状态,并在k8s-node1上新创建两个 Pod,维持总副本数为3,如图所示。
当k8s-node2恢复后,Terminating的Pod会被删除,不过已经运行的Pod不会重新调度回k8s-node2,如图所示。
删除nginx-deployment,如图所示。
5.1.6 用label控制Pod的位置
默认配置下,Scheduler会将Pod调度到所有可用的Node。不过有些情况我们希望将Pod部署到指定的Node,比如将有大量磁盘I/O的 Pod部署到配置了SSD的Node;或者Pod需要GPU,需要运行在配置了GPU的节点上。
Kubernetes是通过label来实现这个功能的。
label是key-value对,各种资源都可以设置label,灵活添加各种自定义属性。比如执行如下命令标注k8s-node1是配置了SSD的节点。
kubectl label node k8s-node1 disktype=ssd
然后通过kubectl get node --show-labels查看节点的label,如图所示。
disktype=ssd已经成功添加到k8s-node1,除了disktype,Node还有几个Kubernetes自己维护的label。
有了disktype这个自定义label,接下来就可以指定将Pod部署到k8s-node1。编辑nginx.yml,如图所示。
在Pod模板的spec里通过nodeSelector指定将此Pod部署到具有label disktype=ssd的Node上。
部署Deployment并查看Pod的运行节点,如图所示。
全部6个副本都运行在k8s-node1上,符合我们的预期。要删除label disktype,执行如下命令:
kubectl label node k8s-node1 disktype-
- 即删除,如图所示。
不过此时Pod并不会重新部署,依然在k8s-node1上运行,如图所示。
除非在nginx.yml中删除nodeSelector设置,然后通过kubectl apply重新部署,如图所示。
Kubernetes会删除之前的Pod并调度和运行新的Pod。
以上是关于每天5分钟玩转Kubernetes | Deployment的主要内容,如果未能解决你的问题,请参考以下文章
每天5分钟玩转Kubernetes | Kubernetes Dashboard安装
每天5分钟玩转Kubernetes | Deployment
每天5分钟玩转Kubernetes | Deployment