zoukankan      html  css  js  c++  java
  • Kubernetes 控制器之 Deployment 介绍(六)

    一、Deployment、ReplicaSet、Pod之间的关系

    我们接着前面的文章说,如果不清楚的请查看之前的博文:http://blog.51cto.com/wzlinux/2322616

    前面我们已经了解到,Kubernetes 通过各种 Controller 来管理 Pod 的生命周期。为了满足不同业务场景,Kubernetes 开发了 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等多种 Controller。我们首先学习最常用的 Deployment。

    1、运行 Deployment

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

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

    上面的命令将部署包含两个副本的 Deployment nginx-deployment,容器的 image 为 nginx:1.7.9

    2、查看 Deployment(deploy)

    查看刚刚创建的 deployment,其可以简写为deploy。

    [root@master ~]# kubectl get deploy
    NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   2         2         2            2           4m56s
    

    使用命令kubectl describe deploy查看内部内容。

    kubectl describe deploy nginx-deployment
    
    Name:                   nginx-deployment
    Namespace:              default
    CreationTimestamp:      Thu, 29 Nov 2018 17:47:16 +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-5fd98dbf5f (2/2 replicas created)
    Events:
      Type    Reason             Age    From                   Message
      ----    ------             ----   ----                   -------
      Normal  ScalingReplicaSet  6m11s  deployment-controller  Scaled up replica set nginx-deployment-5fd98dbf5f to 2
    

    展示的内容大部分都是描述信息,我们看最后一行,这里告诉我们创建了一个 ReplicaSet nginx-deployment-5fd98dbf5f,Events 是 Deployment 的日志,记录了 ReplicaSet 的启动过程。

    通过上面的分析,也验证了 Deployment 通过 ReplicaSet 来管理 Pod 的事实。

    3、查看 ReplicaSet(rs)

    查看我们有哪些 rs。

    [root@master ~]# kubectl get rs
    NAME                          DESIRED   CURRENT   READY   AGE
    nginx-deployment-5fd98dbf5f   2         2         2       12m
    

    使用命令kubectl describe rs查看其详细信息。

    kubectl describe rs nginx-deployment-5fd98dbf5f
    
    Name:           nginx-deployment-5fd98dbf5f
    Namespace:      default
    Selector:       pod-template-hash=5fd98dbf5f,run=nginx-deployment
    Labels:         pod-template-hash=5fd98dbf5f
                    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=5fd98dbf5f
               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  13m   replicaset-controller  Created pod: nginx-deployment-5fd98dbf5f-8g7nm
      Normal  SuccessfulCreate  13m   replicaset-controller  Created pod: nginx-deployment-5fd98dbf5f-58c4z
    

    我们可以看到Controlled By: Deployment/nginx-deployment,说明此 ReplicaSet 由 Deployment nginx-deployment
    Events记录了两个副本 Pod 的创建,那我们查看一下 Pod。

    4、查看 Pod

    查看目前的 Pod。

    [root@master ~]# kubectl get pods
    NAME                                READY   STATUS    RESTARTS   AGE
    nginx-deployment-5fd98dbf5f-58c4z   1/1     Running   0          19m
    nginx-deployment-5fd98dbf5f-8g7nm   1/1     Running   0          19m
    

    随便选择一个 Pod,查看其详细信息。

    kubectl describe pod nginx-deployment-5fd98dbf5f-58c4z
    
    Name:               nginx-deployment-5fd98dbf5f-58c4z
    Namespace:          default
    Priority:           0
    PriorityClassName:  <none>
    Node:               node02.wzlinux.com/172.18.8.202
    Start Time:         Thu, 29 Nov 2018 17:47:16 +0800
    Labels:             pod-template-hash=5fd98dbf5f
                        run=nginx-deployment
    Annotations:        <none>
    Status:             Running
    IP:                 10.244.2.3
    Controlled By:      ReplicaSet/nginx-deployment-5fd98dbf5f
    Containers:
      nginx-deployment:
        Container ID:   docker://69fa73ed16d634627b69b8968915d9a5704f159206ac0d3b2f1179fa99acd56f
        Image:          nginx:1.7.9
        Image ID:       docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
        Port:           <none>
        Host Port:      <none>
        State:          Running
          Started:      Thu, 29 Nov 2018 17:47:28 +0800
        Ready:          True
        Restart Count:  0
        Environment:    <none>
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from default-token-sm664 (ro)
    Conditions:
      Type              Status
      Initialized       True 
      Ready             True 
      ContainersReady   True 
      PodScheduled      True 
    Volumes:
      default-token-sm664:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  default-token-sm664
        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  20m   default-scheduler            Successfully assigned default/nginx-deployment-5fd98dbf5f-58c4z to node02.wzlinux.com
      Normal  Pulling    20m   kubelet, node02.wzlinux.com  pulling image "nginx:1.7.9"
      Normal  Pulled     20m   kubelet, node02.wzlinux.com  Successfully pulled image "nginx:1.7.9"
      Normal  Created    20m   kubelet, node02.wzlinux.com  Created container
      Normal  Started    20m   kubelet, node02.wzlinux.com  Started container
    

    我们可以看到Controlled By: ReplicaSet/nginx-deployment-5fd98dbf5f,说明此 Pod 是由 ReplicaSet nginx-deployment-5fd98dbf5f 创建的。
    Events记录了 Pod 的启动过程。

    5、总结

    1. 用户通过 kubectl 创建 Deployment。
    2. Deployment 创建 ReplicaSet。
    3. ReplicaSet 创建 Pod。

    从上图也可以看出,对象的命名方式是:子对象的名字 = 父对象名字 + 随机字符串或数字。

    二、伸缩

    伸缩(Scale Up/Down)是指在线增加或减少 Pod 的副本数。

    我们重新创建一下。

    [root@master ~]# kubectl run nginx --image=nginx:1.7.9 --replicas=2
    deployment.apps/nginx created
    
    [root@master ~]# kubectl get pod -o wide
    NAME                    READY   STATUS    RESTARTS   AGE   IP            NODE                 NOMINATED NODE
    nginx-699ff78c9-2xxnj   1/1     Running   0          51s   10.244.1.11   node01.wzlinux.com   <none>
    nginx-699ff78c9-j5w6c   1/1     Running   0          51s   10.244.3.6    node02.wzlinux.com   <none>
    

    我们把副本数量修改为5个,查看一下。

    [root@master ~]# kubectl scale --replicas=5 deploy/nginx
    deployment.extensions/nginx scaled
    
    [root@master ~]# kubectl get pod -o wide
    NAME                    READY   STATUS    RESTARTS   AGE     IP            NODE                 NOMINATED NODE
    nginx-699ff78c9-2xxnj   1/1     Running   0          2m21s   10.244.1.11   node01.wzlinux.com   <none>
    nginx-699ff78c9-4qq9h   1/1     Running   0          18s     10.244.1.12   node01.wzlinux.com   <none>
    nginx-699ff78c9-b6dt4   1/1     Running   0          18s     10.244.3.7    node02.wzlinux.com   <none>
    nginx-699ff78c9-j5w6c   1/1     Running   0          2m21s   10.244.3.6    node02.wzlinux.com   <none>
    nginx-699ff78c9-zhwsz   1/1     Running   0          18s     10.244.3.8    node02.wzlinux.com   <none>
    

    三个新副本被创建并调度到 node01 和 node02 上,出于安全考虑,默认配置下 Kubernetes 不会将 Pod 调度到 Master 节点。如果希望将 master 也当作 Node 使用,可以执行如下命令:

    kubectl taint node master node-role.kubernetes.io/master-
    

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

    kubectl taint node master node-role.kubernetes.io/master="":NoSchedule
    

    想要减少副本数量也是同样的方法,指定数量即可,那我们减少到3个副本。

    [root@master ~]# kubectl get pod -o wide
    NAME                    READY   STATUS    RESTARTS   AGE     IP            NODE                 NOMINATED NODE
    nginx-699ff78c9-2xxnj   1/1     Running   0          2m55s   10.244.1.11   node01.wzlinux.com   <none>
    nginx-699ff78c9-4qq9h   1/1     Running   0          52s     10.244.1.12   node01.wzlinux.com   <none>
    nginx-699ff78c9-j5w6c   1/1     Running   0          2m55s   10.244.3.6    node02.wzlinux.com   <none>
    

    三、故障转移

    目前是五个应用分别运行在两台机器上面,我们把 node02 关闭,造成 node02 出现问题,然后再查看一下 Pod 的情况。

    [root@master ~]# kubectl get pod -o wide
    NAME                    READY   STATUS    RESTARTS   AGE     IP            NODE                 NOMINATED NODE
    nginx-699ff78c9-2xxnj   1/1     Running   0          8m49s   10.244.1.11   node01.wzlinux.com   <none>
    nginx-699ff78c9-4qq9h   1/1     Running   0          6m46s   10.244.1.12   node01.wzlinux.com   <none>
    nginx-699ff78c9-j5w6c   1/1     Unknown   0          8m49s   10.244.3.6    node02.wzlinux.com   <none>
    nginx-699ff78c9-wqd5k   1/1     Running   0          32s     10.244.1.13   node01.wzlinux.com   <none>
    

    等待一段时间之后,我们看到 node02 上的 Pod 标记为 Unknown 状态,并在 node01 上面新建三个 Pod,维持总副本数为3。

    那我们重启把服务器启动起来,正常情况下,如果配置没有问题,服务会自动添加到集群中,我们启动查看状态。

    [root@master ~]# kubectl get pod -o wide
    NAME                    READY   STATUS    RESTARTS   AGE     IP            NODE                 NOMINATED NODE
    nginx-699ff78c9-2xxnj   1/1     Running   0          14m     10.244.1.11   node01.wzlinux.com   <none>
    nginx-699ff78c9-4qq9h   1/1     Running   0          12m     10.244.1.12   node01.wzlinux.com   <none>
    nginx-699ff78c9-wqd5k   1/1     Running   0          6m37s   10.244.1.13   node01.wzlinux.com   <none>
    

    当 node02 恢复后,Unknown 的 Pod 会被删除,不过已经运行的 Pod 不会重新调度回 node02。

    四、标签

    默认配置下,Scheduler 会将 Pod 调度到所有可用的 Node。不过有些情况我们希望将 Pod 部署到指定的 Node,比如将有大量磁盘 I/O 的 Pod 部署到配置了 SSD 的 Node;或者 Pod 需要 GPU,需要运行在配置了 GPU 的节点上。

    我们使用mytest.yaml文件创建一个Deployment,内容如下:

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: mytest
      namespace: default
    spec:
      replicas: 5
      template:
        metadata:
          labels:
            run: mytest
        spec:
          containers:
          - image: wangzan18/mytest:v1
            imagePullPolicy: IfNotPresent
            name: mytest
    

    使用下面命令创建应用。

    [root@master ~]# kubectl create -f mytest.yaml 
    deployment.extensions/mytest created
    

    Kubernetes 是通过 label 来实现这个功能的。label 是 key-value 对,各种资源都可以设置 label,灵活添加各种自定义属性。比如执行如下命令标注 node01 是配置了 SSD 的节点。

    kubectl label node node01.wzlinux.com disktype=ssd
    

    然后使用命令kubectl get node --show-labels我们查看。

    NAME                 STATUS   ROLES    AGE   VERSION   LABELS
    master.wzlinux.com   Ready    master   26h   v1.12.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=master.wzlinux.com,node-role.kubernetes.io/master=
    node01.wzlinux.com   Ready    <none>   25h   v1.12.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/hostname=node01.wzlinux.com
    node02.wzlinux.com   Ready    <none>   91m   v1.12.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=node02.wzlinux.com
    

    disktype=ssd 已经成功添加到 node01,除了 disktype,Node 还有几个 Kubernetes 自己维护的 label。

    有了disktype这个自定义 label,接下来就可以指定将 Pod 部署到 node01。编辑 mytest.yaml:

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: mytest
      namespace: default
    spec:
      replicas: 5
      template:
        metadata:
          labels:
            run: mytest
        spec:
          containers:
          - image: wangzan18/mytest:v1
            imagePullPolicy: IfNotPresent
            name: mytest
          nodeSelector:
            disktype: ssd
    

    在 Pod 模板的spec里通过nodeSelector指定将此 Pod 部署到具有 label disktype=ssd 的 Node 上。

    重新部署 Deployment 并查看 Pod 的运行节点:

    [root@master ~]# kubectl apply -f mytest.yaml 
    Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
    deployment.extensions/mytest configured
    
    [root@master ~]# kubectl get pod -o wide
    NAME                      READY   STATUS    RESTARTS   AGE   IP            NODE                 NOMINATED NODE
    mytest-6f7fbbfdc7-2tr6s   1/1     Running   0          63s   10.244.1.19   node01.wzlinux.com   <none>
    mytest-6f7fbbfdc7-5g9tj   1/1     Running   0          61s   10.244.1.21   node01.wzlinux.com   <none>
    mytest-6f7fbbfdc7-bnfxv   1/1     Running   0          61s   10.244.1.22   node01.wzlinux.com   <none>
    mytest-6f7fbbfdc7-bqzqq   1/1     Running   0          60s   10.244.1.23   node01.wzlinux.com   <none>
    mytest-6f7fbbfdc7-v6cqk   1/1     Running   0          63s   10.244.1.20   node01.wzlinux.com   <none>
    

    全部 6 个副本都运行在 node01 上,符合我们的预期。

    要删除 label disktype,执行如下命令:

    [root@master ~]# kubectl label node node01.wzlinux.com disktype-
    node/node01.wzlinux.com labeled
    

    不过此时 Pod 并不会重新部署,依然在 node01 上运行。

    除非在mytest.yaml中删除nodeSelector设置,然后通过kubectl apply重新部署。

    关于对象资源的设定,大家可以使用命令kubectl explain,比如查看pod中nodeSelector的参数设定,我们可以使用命令 kubectl explain pod.spec.nodeSelector

    小问题:手动重新添加到集群

    如果因为某些问题,服务不能自动添加到集群中,我们就需要手动重新初始化添加一次。

    master 节点上面先删除 node02节点。

    kubectl delete node node02.wzlinux.com
    

    node02 上面 reset。

    kubeadm reset
    

    重新使用kubeadm init初始化,但是发现token过期了,我们需要在master节点重新生成token。

    [root@master ~]# kubeadm token create
    v269qh.2mylwtmc96kd28sq
    

    生成ca-cert-hash sha256的值。

    [root@master ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | 
    >    openssl dgst -sha256 -hex | sed 's/^.* //'
    84e50f7beaa4d3296532ae1350330aaf79f3f0d45ec8623fae6cd9fe9a804635
    

    然后在node节点上面重新使用kubeadm init进行添加集群中。

  • 相关阅读:
    关闭编辑easyui datagrid table
    sql 保留两位小数+四舍五入
    easyui DataGrid 工具类之 util js
    easyui DataGrid 工具类之 后台生成列
    easyui DataGrid 工具类之 WorkbookUtil class
    easyui DataGrid 工具类之 TableUtil class
    easyui DataGrid 工具类之 Utils class
    easyui DataGrid 工具类之 列属性class
    oracle 卸载
    “云时代架构”经典文章阅读感想七
  • 原文地址:https://www.cnblogs.com/wzlinux/p/10159303.html
Copyright © 2011-2022 走看看