Skip to content

Deployment

1. 简介

代表一次部署,管理运行1个或多个Pod。Deployment属于无状态应用部署,主要用来部署微服务,提供多副本的能力。 Alt text

2. 创建Deployment

Deployment实际上会创建了一个ReplicaSet类型的工作负载,Deployment自动管理ReplicaSet,比如负责启动三个nginx的Pod:

sh
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:

yml
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的名称以及底层容器的镜像信息。

sh
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:
Alt text

3. 查看Deployment

sh
[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。

sh
## 修改本次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可以按照实际需求进行动态调整副本的数量

sh
[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的故障转移的能力:
Alt text 可以使用删除Deployment命令来释放Pod:

sh
[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. 自愈和故障转移

sh
[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:

sh
[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:

sh
[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: Alt text 隔五分钟后在node101上查看:

sh
[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发现使用的是最新版

sh
[root@node101 ~]# kubectl get -n zk-dev deploy/my-dep -oyaml |grep image
      - image: nginx
        imagePullPolicy: Always

进行版本更新为nginx为1.27.5:

sh
[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的版本,发现已经变化:

sh
[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。这样的部署策略进行下去,如果想要回滚老版本的话,首先查看当前部署版本:

sh
[root@node101 ~]# kubectl rollout history deploy/my-dep -n zk-dev
deployment.apps/my-dep 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

如果进行版本回退,回退到版本1:

sh
[root@node101 ~]# kubectl rollout undo deploy/my-dep --to-revision=1 -n zk-dev
deployment.apps/my-dep rolled back