第七篇:Kubernetes对象之Deployment

1. 前言

前面已经了解到,kubernetes通过Controller来管理Pod的生命周期,为了满足不同的场景需求,Kubernetes开发了Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job等多种Controller。本篇简要学习最常用的Deployment。

2. 运行Deployment

先从一个例子开始,运行一个Deployment

kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2

上面的命令将部署两个副本的Deployment nginx-deployment,容器的image是nginx:1.7.9,下面详细分析Kubernetes都做了哪些工作:

mengqp@mengqp-VirtualBox-01:~$ kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx-deployment created
mengqp@mengqp-VirtualBox-01:~$ kubectl get deployment nginx-deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           21s
mengqp@mengqp-VirtualBox-01:~$

通过kubectl get deployment命令查看nginx-deployment的状态,输出显示两个副本均正常运行。
接下来我们用kubectl describe deployment了解更详细的信息,如下:

mengqp@mengqp-VirtualBox-01:~$ kubectl describe deployment nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Sun, 22 Mar 2020 20:40:18 +0800
Labels:                 run=nginx-deployment
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               run=nginx-deployment
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  run=nginx-deployment
  Containers:
   nginx-deployment:
    Image:        nginx:1.7.9
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-deployment-8476d5f8cd (2/2 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  6m12s  deployment-controller  Scaled up replica set nginx-deployment-8476d5f8cd to 2
mengqp@mengqp-VirtualBox-01:~$

通过上面的命令可以看到Deployment的日志Events如下:

Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  6m12s  deployment-controller  Scaled up replica set nginx-deployment-8476d5f8cd to 2

这里告诉我们创建了一个ReplicaSet nginx-deployment-8476d5f8cd。通过此处分析,验证了Deployment是通过ReplicaSet来管理Pod的,接下来我们看一下nginx-deployment-8476d5f8cd

mengqp@mengqp-VirtualBox-01:~$ kubectl get ReplicaSet
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-8476d5f8cd   2         2         2       10m
mengqp@mengqp-VirtualBox-01:~$ kubectl describe ReplicaSet nginx-deployment-8476d5f8cd
Name:           nginx-deployment-8476d5f8cd
Namespace:      default
Selector:       pod-template-hash=8476d5f8cd,run=nginx-deployment
Labels:         pod-template-hash=8476d5f8cd
                run=nginx-deployment
Annotations:    deployment.kubernetes.io/desired-replicas: 2
                deployment.kubernetes.io/max-replicas: 3
                deployment.kubernetes.io/revision: 1
Controlled By:  Deployment/nginx-deployment
Replicas:       2 current / 2 desired
Pods Status:    2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  pod-template-hash=8476d5f8cd
           run=nginx-deployment
  Containers:
   nginx-deployment:
    Image:        nginx:1.7.9
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  11m   replicaset-controller  Created pod: nginx-deployment-8476d5f8cd-8znd7
  Normal  SuccessfulCreate  11m   replicaset-controller  Created pod: nginx-deployment-8476d5f8cd-49vcf
mengqp@mengqp-VirtualBox-01:~$

由上面的Controlled By指明此ReplicaSet是由Deployment/nginx-deployment创建的。通过Events日志看到replicaset-controller创建了两个Pod,接下来我们查看Pod的信息:

mengqp@mengqp-VirtualBox-01:~$ kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-8476d5f8cd-49vcf   1/1     Running   0          16m
nginx-deployment-8476d5f8cd-8znd7   1/1     Running   0          16m
mengqp@mengqp-VirtualBox-01:~$ kubectl describe pod nginx-deployment-8476d5f8cd-49vcf
Name:         nginx-deployment-8476d5f8cd-49vcf
Namespace:    default
Priority:     0
Node:         mengqp-virtualbox-02/192.168.0.106
Start Time:   Sun, 22 Mar 2020 20:40:18 +0800
Labels:       pod-template-hash=8476d5f8cd
              run=nginx-deployment
Annotations:  <none>
Status:       Running
IP:           10.244.1.12
IPs:
  IP:           10.244.1.12
Controlled By:  ReplicaSet/nginx-deployment-8476d5f8cd
Containers:
  nginx-deployment:
    Container ID:   docker://31ad2b7e629dfe0c530be1dbcb1cdd0cd4dacebef16ba7438a1c50db4f2cab4e
    Image:          nginx:1.7.9
    Image ID:       docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 22 Mar 2020 20:40:19 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-rxm5w (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-rxm5w:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-rxm5w
    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-deployment-8476d5f8cd-49vcf to mengqp-virtualbox-02
  Normal  Pulled     17m        kubelet, mengqp-virtualbox-02  Container image "nginx:1.7.9" already present on machine
  Normal  Created    17m        kubelet, mengqp-virtualbox-02  Created container nginx-deployment
  Normal  Started    17m        kubelet, mengqp-virtualbox-02  Started container nginx-deployment
mengqp@mengqp-VirtualBox-01:~$

Controlled By 指明了此Pod是由ReplicaSet/nginx-deployment-8476d5f8cd创建的。Events记录了Pod的启动过程,如果操作失败(比如镜像不存在等)也可以在这里查到原因。
总结一下这个过程:
(1)、用户通过Kubectl创建Deployment。
(2)、Deployment创建ReplicaSet
(3)、ReplicaSet创建Pod
在这里插入图片描述
从上图的名字中也可以看出,对象的命名方式为:“子对象的名字=父对象名字+随机字符串或数字”

3、命令和配置文件创建Deployment比较

(1)、用kubectl命令直接创建,比如“kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2”
(2)、通过配置文件和kubectl apply来创建。要完成前面同样的工作,可以执行“kubectl apply -f nginx.yml”,nginx.yml的内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: my-nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
        name: nginx
        image: nginx:1.7.9

资源的属性写在配置文件中,文件格式为YAML。
下面对这两种方式进行比较:
(1)、基于命令的方式:

  • 简单、直观、快捷、上手快

  • 适合临时测试或实验
    (2)、基于配置文件的方式:

  • 配置文件描述了What,即应用最终要达到的状态。

  • 配置文件提供了创建资源的模板,可以重复部署

  • 可以像管理代码一样管理部署

  • 适合正式的、跨环境的、规模化部署

  • 这种方式要求熟悉配置文件的语法,有一定难度

4、Deployment配置文件简介

既然要用YAM配置文件部署应用,现在有必要了解一下Deployment的配置格式了,其他Controller(比如DaemonSet)非常类似。
以nginx-deployment为例,配置文件如下:

apiVersion: apps/v1  (1)
kind: Deployment  (2)
metadata: (3)
  name: nginx-deployment
spec: (4)
  selector: (5)
    matchLabels:
      app: my-nginx
  replicas: 2 (6)
  template: (7)
    metadata: (8)
      labels:
        app: my-nginx
    spec: (9)
      containers:
      - name: nginx
        image: nginx:1.7.9

(1)apiVersion是当前配置格式的版本,可以使用kubectl api-versions查看,不同版本,配置不同
(2)kind是要创建的资源类型,这里是Deployment
(3)metadata是该资源的元数据,name是必需的元数据项
(4)spec部分是该Deployment的规格说明(查看帮助kubectl explain Deployment.spec)
(5)selector是pod的标签选择器。 由此选择其pod的现有ReplicaSet(副本集)将受此部署影响的副本。
(6)replicas指明副本数量,默认为1
(7)template定义Pod的模板,这是配置文件的重要部分
(8)metadata定义Pod的元数据,至少要定义一个label。label的key和value可以任意指定
(9)spec描述Pod的规格,此部分定义Pod中每一个容器的属性,name和image是必需的。
#总结:
1,在Deployment中必须写matchLables,
2,在定义模板的时候必须定义labels,因为Deployment.spec.selector是必须字段,而他又必须和template.labels对应,
3,template里面定义的内容会应用到下面所有的副本集里面,在template.spec.containers里面不能定义labels标签.

执行完kubectl apply -f nginx.yml后,根据命令可以看到Deployment、ReplicaSet、Pod都已经就绪,如果要删除这些资源,执行kubectl delete deployment nginx-deployment 或 kubectl delete -f nginx.yml

5、伸缩

伸缩是指在线增加或减少Pod的副本数。
nginx-deployment初始副本是2个,如下:

mengqp@mengqp-VirtualBox-01:~$ kubectl apply -f nginx.yml
deployment.apps/nginx-deployment created
mengqp@mengqp-VirtualBox-01:~$ kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP            NODE                   NOMINATED NODE   READINESS GATES
nginx-deployment-67f56d94f7-w6l5x   1/1     Running   0          11s   10.244.1.14   mengqp-virtualbox-02   <none>           <none>
nginx-deployment-67f56d94f7-x9pzt   1/1     Running   0          11s   10.244.2.12   mengqp-virtualbox-03   <none>           <none>
mengqp@mengqp-VirtualBox-01:~$

现在修改nginx.yml的配置项replicas修改副本数为5个,再次执行kubectl apply nginx.yml,如下:

mengqp@mengqp-VirtualBox-01:~$ kubectl apply -f nginx.yml
deployment.apps/nginx-deployment configured
mengqp@mengqp-VirtualBox-01:~$ kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP            NODE                   NOMINATED NODE   READINESS GATES
nginx-deployment-67f56d94f7-4xr79   1/1     Running   0          3s      10.244.1.15   mengqp-virtualbox-02   <none>           <none>
nginx-deployment-67f56d94f7-k5wn7   1/1     Running   0          3s      10.244.1.16   mengqp-virtualbox-02   <none>           <none>
nginx-deployment-67f56d94f7-t4lzj   1/1     Running   0          3s      10.244.2.13   mengqp-virtualbox-03   <none>           <none>
nginx-deployment-67f56d94f7-w6l5x   1/1     Running   0          4m29s   10.244.1.14   mengqp-virtualbox-02   <none>           <none>
nginx-deployment-67f56d94f7-x9pzt   1/1     Running   0          4m29s   10.244.2.12   mengqp-virtualbox-03   <none>           <none>

三个新的副本又被调度到两台node节点上了

出于安全考虑,默认Kubernetes不会将Pod调度到Master节点。如果希望将k8s-master也当做Node使用,可以执行如下命令:

mengqp@mengqp-VirtualBox-01:~$ kubectl taint node mengqp-virtualbox-01 node-role.kubernetes.io/master-
node/mengqp-virtualbox-01 untainted
mengqp@mengqp-VirtualBox-01:~$

如果要恢复Master only状态,执行如下命令:

mengqp@mengqp-VirtualBox-01:~$ kubectl taint node mengqp-virtualbox-01 node-role.kubernetes.io/master="":NoSchedule
node/mengqp-virtualbox-01 tainted
mengqp@mengqp-VirtualBox-01:~$

6、Failover

如果node1节点由于网络或其他原因不通了,Kubernetes会检查到该节点不可用,将node1上的Pod状态标位Unknown,并在node2上新建Pod,来维持总的副本数,当node1恢复后,Unknown的pod会被删除,不过已经运行的Pod不会被重新调度会node1。

7、用label控制Pod的位置

默认配置下,Scheduler会将Pod调度到所有可用的Node。不过有些情况我们希望将Pod部署到指定的Node上,比如将有大量磁盘I/O的Pod部署到配置了SSD的Node。Kubectl 是通过label来实现这个功能的。
label是key-value对,各种资源都可以设置label,灵活添加各种自定义属性。比如执行如下命令标注node1是配置了SSD的节点。

mengqp@mengqp-VirtualBox-01:~$ kubectl label node mengqp-virtualbox-02 disktype=ssd
node/mengqp-virtualbox-01 labeled
mengqp@mengqp-VirtualBox-01:~$

然后通过如下命令:

mengqp@mengqp-VirtualBox-01:~$ kubectl get node --show-labels
NAME                   STATUS   ROLES    AGE   VERSION   LABELS
mengqp-virtualbox-01   Ready    master   14d   v1.17.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=mengqp-virtualbox-01,kubernetes.io/os=linux,node-role.kubernetes.io/master=
mengqp-virtualbox-02   Ready    node     13d   v1.17.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=mengqp-virtualbox-02,kubernetes.io/os=linux,node-role.kubernetes.io/node=
mengqp-virtualbox-03   Ready    node     13d   v1.17.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=mengqp-virtualbox-03,kubernetes.io/os=linux,node-role.kubernetes.io/node=
mengqp@mengqp-VirtualBox-01:~$

有了disktype这个自定义的label,接下来就可以指定将pod部署到那台node节点上。编辑nginx.yml,如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: my-nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
      nodeSelector:
        disktype: ssd

部署成功后,查看pod信息,发现pod都被部署到了有该label的节点上了。
要删除label disktype,执行如下命令:

kubectl label node mengqp-virtualbox-02 disktype-

删除label之后,pod不会自动重新调度,除非重新部署。

发布了47 篇原创文章 · 获赞 0 · 访问量 1162

猜你喜欢

转载自blog.csdn.net/weixin_43103748/article/details/104963619