Deployment
1. 简介
代表一次部署,管理运行1个或多个Pod。Deployment属于无状态应用部署,主要用来部署微服务,提供多副本的能力。
2. 创建Deployment
Deployment实际上会创建了一个ReplicaSet类型的工作负载,Deployment自动管理ReplicaSet,比如负责启动三个nginx的Pod:
kubectl create deployment my-dep --image=nginx --replicas=3 -n zk-dev
[root@node101 ~]# kubectl get pod -n zk-dev -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-dep-7565875b9c-9vr4w 1/1 Running 0 34s 192.168.200.88 node102 <none> <none>
my-dep-7565875b9c-cr262 1/1 Running 0 34s 192.168.227.90 cluster-endpoint <none> <none>
my-dep-7565875b9c-qhzrk 1/1 Running 0 34s 192.168.111.155 node103 <none> <none>
会发现my-dep后面还带有随机字符串,并且分别在三个节点上面。通过yaml文件也可以创建Deployment,编写nginx-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
namespace: zk-dev
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21.5
ports:
- containerPort: 80
其中spec.replicas
字段标明Pod副本的数量,spec.matchLabels.matchLabels
字段标明所创建的ReplicaSet标签,spec.template
字段标明Pod的名称以及底层容器的镜像信息。
kubectl apply -f nginx-deployment.yaml
## 查看部署信息
[root@node101 ~]# kubectl get deploy -n zk-dev
NAME READY UP-TO-DATE AVAILABLE AGE
my-dep 3/3 3 3 33m
nginx-deployment 3/3 3 3 39s
还可以在Dashboard界面上创建Deployment:
3. 查看Deployment
[root@node101 ~]# kubectl describe deployment my-dep -n zk-dev
Name: my-dep
Namespace: zk-dev
CreationTimestamp: Sun, 17 Aug 2025 08:39:07 +0800
Labels: app=my-dep
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=my-dep
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=my-dep
Containers:
nginx:
Image: nginx
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: my-dep-7565875b9c (3/3 replicas created)
Events: <none>
4. 变更Deployment
Deployment中只有修改spec.template
信息才会重新构建Pod, 其他的属性修改比如副本数量等只是更改Pod个数,不会触发修改Pod。
## 修改本次nginx-deployment部署信息
kubectl edit deployment/nginx-deployment -n zk-dev
## 修改部署的副本为2
[root@node101 ~]# kubectl edit deployment/my-dep -n zk-dev
deployment.apps/my-dep edited
[root@node101 ~]# kubectl get pod -n zk-dev
NAME READY STATUS RESTARTS AGE
my-dep-7565875b9c-cr262 1/1 Running 0 4h18m
my-dep-7565875b9c-qhzrk 1/1 Running 0 4h18m
myapp 2/2 Running 2 (4h34m ago) 4d5h
5. 扩缩Deployment
Deployment可以按照实际需求进行动态调整副本的数量
[root@node101 ~]# kubectl scale deployment/my-dep -n zk-dev --replicas=5
deployment.apps/my-dep scaled
[root@node101 ~]# kubectl get pod -owide -n zk-dev
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-dep-7565875b9c-cr262 1/1 Running 0 4h9m 192.168.227.90 cluster-endpoint <none> <none>
my-dep-7565875b9c-kcwt8 1/1 Running 0 29s 192.168.111.158 node103 <none> <none>
my-dep-7565875b9c-qhzrk 1/1 Running 0 4h9m 192.168.111.155 node103 <none> <none>
my-dep-7565875b9c-zj294 1/1 Running 0 29s 192.168.200.93 node102 <none> <none>
my-dep-7565875b9c-zm2lt 1/1 Running 0 98m 192.168.200.92 node102 <none> <none>
myapp 2/2 Running 2 (4h26m ago) 4d5h 192.168.111.152 node103 <none> <none>
6. 删除Deployment
如果直接删除Pod, 会发现Deployment具有自愈能力,删除后Pod又会被重新启动,这是Deployment的故障转移的能力: 可以使用删除Deployment命令来释放Pod:
[root@node101 ~]# kubectl delete deploy nginx-deployment -n zk-dev
deployment.apps "nginx-deployment" deleted
[root@node101 ~]# kubectl get pod -n zk-dev
NAME READY STATUS RESTARTS AGE
my-dep-7565875b9c-cr262 1/1 Running 0 3h35m
my-dep-7565875b9c-qhzrk 1/1 Running 0 3h35m
my-dep-7565875b9c-zm2lt 1/1 Running 0 64m
myapp 2/2 Running 2 (3h51m ago) 4d4h
7. 自愈和故障转移
[root@node101 ~]# kubectl get pod -n zk-dev -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-dep-7565875b9c-cr262 1/1 Running 0 4h42m 192.168.227.90 cluster-endpoint <none> <none>
my-dep-7565875b9c-qhzrk 1/1 Running 0 4h42m 192.168.111.155 node103 <none> <none>
myapp 2/2 Running 2 (4h59m ago) 4d5h 192.168.111.152 node103 <none> <none>
发现node103上面部署了1个my-dep的Pod, 登录到node103,然后停掉名叫my-dep-7565875b9c-qhzrk的pod:
[root@node103 ~]# crictl ps
WARN[0000] Config "/etc/crictl.yaml" does not exist, trying next: "/usr/bin/crictl.yaml"
WARN[0000] runtime connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
WARN[0000] Image connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD NAMESPACE
f74977e1541e8 605c77e624ddb 5 hours ago Running nginx 0 cd5b299e05c08 my-dep-7565875b9c-qhzrk zk-dev
b5e9421cf9cf3 a9de0489eb32f 5 hours ago Running kubernetes-dashboard-auth 4 0c85e5dbffd99 kubernetes-dashboard-auth-856496d66b-qvrx9 kubernetes-dashboard
640c7be990a3e 47f7e766e8138 5 hours ago Running tomcat 1 b3248db232ae3 myapp zk-dev
a58b31f0dc921 605c77e624ddb 5 hours ago Running nginx 1 b3248db232ae3 myapp zk-dev
9a9d7fc4b0d23 21d503bfc17d6 5 hours ago Running proxy 3 3343d1c87c894 kubernetes-dashboard-kong-846576b479-wkl4l kubernetes-dashboard
0df552f7a4eca d9cbc9f4053ca 5 hours ago Running kubernetes-dashboard-metrics-scraper 4 d528b3f89fc1f kubernetes-dashboard-metrics-scraper-79988d66c9-w9vm5 kubernetes-dashboard
a13c4cc2c1aaa 08616d26b8e74 5 hours ago Running calico-node 5 4f0edc1ef1628 calico-node-25pnt kube-system
356bbd68ab1e3 f1184a0bd7fe5 5 hours ago Running kube-proxy 5 60d54f398f7ac kube-proxy-kcrrf kube-system
发现容器id是f74977e1541e8:
[root@node103 ~]# crictl stop f74977e1541e8
WARN[0000] Config "/etc/crictl.yaml" does not exist, trying next: "/usr/bin/crictl.yaml"
WARN[0000] runtime connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
f74977e1541e8
## 停掉容器后发现容器又被启动起来了
[root@node103 ~]# crictl ps
WARN[0000] Config "/etc/crictl.yaml" does not exist, trying next: "/usr/bin/crictl.yaml"
WARN[0000] runtime connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
WARN[0000] Image connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD NAMESPACE
2269dbd85c7f2 605c77e624ddb 10 seconds ago Running nginx 1 cd5b299e05c08 my-dep-7565875b9c-qhzrk zk-dev
b5e9421cf9cf3 a9de0489eb32f 5 hours ago Running kubernetes-dashboard-auth 4 0c85e5dbffd99 kubernetes-dashboard-auth-856496d66b-qvrx9 kubernetes-dashboard
640c7be990a3e 47f7e766e8138 5 hours ago Running tomcat 1 b3248db232ae3 myapp zk-dev
a58b31f0dc921 605c77e624ddb 5 hours ago Running nginx 1 b3248db232ae3 myapp zk-dev
9a9d7fc4b0d23 21d503bfc17d6 5 hours ago Running proxy 3 3343d1c87c894 kubernetes-dashboard-kong-846576b479-wkl4l kubernetes-dashboard
0df552f7a4eca d9cbc9f4053ca 5 hours ago Running kubernetes-dashboard-metrics-scraper 4 d528b3f89fc1f kubernetes-dashboard-metrics-scraper-79988d66c9-w9vm5 kubernetes-dashboard
a13c4cc2c1aaa 08616d26b8e74 5 hours ago Running calico-node 5 4f0edc1ef1628 calico-node-25pnt kube-system
356bbd68ab1e3 f1184a0bd7fe5 5 hours ago Running kube-proxy 5 60d54f398f7ac kube-proxy-kcrrf kube-system
如果我们直接关闭node103: 隔五分钟后在node101上查看:
[root@node101 ~]# kubectl get pod -n zk-dev -owide --watch
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-dep-7565875b9c-cr262 1/1 Running 0 4h55m 192.168.227.90 cluster-endpoint <none> <none>
my-dep-7565875b9c-qhzrk 1/1 Running 1 (6m11s ago) 4h55m 192.168.111.155 node103 <none> <none>
myapp 2/2 Running 2 (5h11m ago) 4d5h 192.168.111.152 node103 <none> <none>
my-dep-7565875b9c-qhzrk 1/1 Running 1 (9m39s ago) 4h59m 192.168.111.155 node103 <none> <none>
myapp 2/2 Running 2 (5h15m ago) 4d5h 192.168.111.152 node103 <none> <none>
my-dep-7565875b9c-qhzrk 1/1 Terminating 1 (9m39s ago) 4h59m 192.168.111.155 node103 <none> <none>
myapp 2/2 Terminating 2 (5h15m ago) 4d5h 192.168.111.152 node103 <none> <none>
my-dep-7565875b9c-9vb4m 0/1 Pending 0 0s <none> <none> <none> <none>
my-dep-7565875b9c-9vb4m 0/1 Pending 0 0s <none> node102 <none> <none>
my-dep-7565875b9c-9vb4m 0/1 ContainerCreating 0 0s <none> node102 <none> <none>
my-dep-7565875b9c-9vb4m 0/1 ContainerCreating 0 1s <none> node102 <none> <none>
my-dep-7565875b9c-9vb4m 1/1 Running 0 2s 192.168.200.94 node102 <none> <none>
加上--watch表示记录pod变更,可以发现原本部署在node103上面的my-dep被转移到了node102上面了。
8. 回滚Deployment
查看当前nginx发现使用的是最新版
[root@node101 ~]# kubectl get -n zk-dev deploy/my-dep -oyaml |grep image
- image: nginx
imagePullPolicy: Always
进行版本更新为nginx为1.27.5:
[root@node101 ~]# kubectl set image deploy/my-dep nginx=swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.5 -n zk-dev
deployment.apps/my-dep image updated
## 查看Deployment变更状态
[root@node101 ~]# kubectl rollout status deploy/my-dep -n zk-dev
deployment "my-dep" successfully rolled out
查看当前nginx的版本,发现已经变化:
[root@node101 ~]kubectl get -n zk-dev deploy/my-dep -oyaml |grep imagege
- image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.5
imagePullPolicy: Always
[root@node101 ~]# kubectl get pod -n zk-dev -w
NAME READY STATUS RESTARTS AGE
my-dep-7565875b9c-jhsqh 1/1 Running 0 10s
my-dep-7565875b9c-z5fsz 1/1 Running 0 11s
my-dep-59cf8c8bb7-99hwf 0/1 Pending 0 0s
my-dep-59cf8c8bb7-99hwf 0/1 Pending 0 0s
my-dep-59cf8c8bb7-99hwf 0/1 ContainerCreating 0 0s
my-dep-59cf8c8bb7-99hwf 0/1 ContainerCreating 0 1s
my-dep-59cf8c8bb7-99hwf 1/1 Running 0 2s
my-dep-7565875b9c-z5fsz 1/1 Terminating 0 24s
my-dep-59cf8c8bb7-bg746 0/1 Pending 0 0s
my-dep-59cf8c8bb7-bg746 0/1 Pending 0 0s
my-dep-59cf8c8bb7-bg746 0/1 ContainerCreating 0 0s
my-dep-7565875b9c-z5fsz 1/1 Terminating 0 24s
my-dep-7565875b9c-z5fsz 0/1 Completed 0 24s
my-dep-59cf8c8bb7-bg746 0/1 ContainerCreating 0 0s
my-dep-7565875b9c-z5fsz 0/1 Completed 0 25s
my-dep-7565875b9c-z5fsz 0/1 Completed 0 25s
my-dep-59cf8c8bb7-bg746 1/1 Running 0 1s
my-dep-7565875b9c-jhsqh 1/1 Terminating 0 24s
my-dep-7565875b9c-jhsqh 1/1 Terminating 0 24s
my-dep-7565875b9c-jhsqh 0/1 Completed 0 24s
my-dep-7565875b9c-jhsqh 0/1 Completed 0 24s
my-dep-7565875b9c-jhsqh 0/1 Completed 0 24s
可以看到Deployment进行版本部署的时候,是先启动新版本后再停止掉一个老版本的Pod, 然后再启动一个新版本后再停止一个老版本的Pod。这样的部署策略进行下去,如果想要回滚老版本的话,首先查看当前部署版本:
[root@node101 ~]# kubectl rollout history deploy/my-dep -n zk-dev
deployment.apps/my-dep
REVISION CHANGE-CAUSE
1 <none>
2 <none>
如果进行版本回退,回退到版本1:
[root@node101 ~]# kubectl rollout undo deploy/my-dep --to-revision=1 -n zk-dev
deployment.apps/my-dep rolled back