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

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

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

1、运行 Deployment

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

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

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

2、查看 Deployment(deploy)

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

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

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

  1. kubectl describe deploy nginx-deployment
  1. Name: nginx-deployment
  2. Namespace: default
  3. CreationTimestamp: Thu, 29 Nov 2018 17:47:16 +0800
  4. Labels: run=nginx-deployment
  5. Annotations: deployment.kubernetes.io/revision: 1
  6. Selector: run=nginx-deployment
  7. Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
  8. StrategyType: RollingUpdate
  9. MinReadySeconds: 0
  10. RollingUpdateStrategy: 25% max unavailable, 25% max surge
  11. Pod Template:
  12. Labels: run=nginx-deployment
  13. Containers:
  14. nginx-deployment:
  15. Image: nginx:1.7.9
  16. Port: <none>
  17. Host Port: <none>
  18. Environment: <none>
  19. Mounts: <none>
  20. Volumes: <none>
  21. Conditions:
  22. Type Status Reason
  23. ---- ------ ------
  24. Available True MinimumReplicasAvailable
  25. Progressing True NewReplicaSetAvailable
  26. OldReplicaSets: <none>
  27. NewReplicaSet: nginx-deployment-5fd98dbf5f (2/2 replicas created)
  28. Events:
  29. Type Reason Age From Message
  30. ---- ------ ---- ---- -------
  31. 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。

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

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

  1. kubectl describe rs nginx-deployment-5fd98dbf5f
  1. Name: nginx-deployment-5fd98dbf5f
  2. Namespace: default
  3. Selector: pod-template-hash=5fd98dbf5f,run=nginx-deployment
  4. Labels: pod-template-hash=5fd98dbf5f
  5. run=nginx-deployment
  6. Annotations: deployment.kubernetes.io/desired-replicas: 2
  7. deployment.kubernetes.io/max-replicas: 3
  8. deployment.kubernetes.io/revision: 1
  9. Controlled By: Deployment/nginx-deployment
  10. Replicas: 2 current / 2 desired
  11. Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed
  12. Pod Template:
  13. Labels: pod-template-hash=5fd98dbf5f
  14. run=nginx-deployment
  15. Containers:
  16. nginx-deployment:
  17. Image: nginx:1.7.9
  18. Port: <none>
  19. Host Port: <none>
  20. Environment: <none>
  21. Mounts: <none>
  22. Volumes: <none>
  23. Events:
  24. Type Reason Age From Message
  25. ---- ------ ---- ---- -------
  26. Normal SuccessfulCreate 13m replicaset-controller Created pod: nginx-deployment-5fd98dbf5f-8g7nm
  27. 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。

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

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

  1. kubectl describe pod nginx-deployment-5fd98dbf5f-58c4z
  1. Name: nginx-deployment-5fd98dbf5f-58c4z
  2. Namespace: default
  3. Priority: 0
  4. PriorityClassName: <none>
  5. Node: node02.wzlinux.com/172.18.8.202
  6. Start Time: Thu, 29 Nov 2018 17:47:16 +0800
  7. Labels: pod-template-hash=5fd98dbf5f
  8. run=nginx-deployment
  9. Annotations: <none>
  10. Status: Running
  11. IP: 10.244.2.3
  12. Controlled By: ReplicaSet/nginx-deployment-5fd98dbf5f
  13. Containers:
  14. nginx-deployment:
  15. Container ID: docker://69fa73ed16d634627b69b8968915d9a5704f159206ac0d3b2f1179fa99acd56f
  16. Image: nginx:1.7.9
  17. Image ID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
  18. Port: <none>
  19. Host Port: <none>
  20. State: Running
  21. Started: Thu, 29 Nov 2018 17:47:28 +0800
  22. Ready: True
  23. Restart Count: 0
  24. Environment: <none>
  25. Mounts:
  26. /var/run/secrets/kubernetes.io/serviceaccount from default-token-sm664 (ro)
  27. Conditions:
  28. Type Status
  29. Initialized True
  30. Ready True
  31. ContainersReady True
  32. PodScheduled True
  33. Volumes:
  34. default-token-sm664:
  35. Type: Secret (a volume populated by a Secret)
  36. SecretName: default-token-sm664
  37. Optional: false
  38. QoS Class: BestEffort
  39. Node-Selectors: <none>
  40. Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
  41. node.kubernetes.io/unreachable:NoExecute for 300s
  42. Events:
  43. Type Reason Age From Message
  44. ---- ------ ---- ---- -------
  45. Normal Scheduled 20m default-scheduler Successfully assigned default/nginx-deployment-5fd98dbf5f-58c4z to node02.wzlinux.com
  46. Normal Pulling 20m kubelet, node02.wzlinux.com pulling image "nginx:1.7.9"
  47. Normal Pulled 20m kubelet, node02.wzlinux.com Successfully pulled image "nginx:1.7.9"
  48. Normal Created 20m kubelet, node02.wzlinux.com Created container
  49. 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 的副本数。

我们重新创建一下。

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

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

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

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

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

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

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

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

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

三、故障转移

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

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

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

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

  1. [root@master ~]# kubectl get pod -o wide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
  3. nginx-699ff78c9-2xxnj 1/1 Running 0 14m 10.244.1.11 node01.wzlinux.com <none>
  4. nginx-699ff78c9-4qq9h 1/1 Running 0 12m 10.244.1.12 node01.wzlinux.com <none>
  5. 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,内容如下:

  1. apiVersion: extensions/v1beta1
  2. kind: Deployment
  3. metadata:
  4. name: mytest
  5. namespace: default
  6. spec:
  7. replicas: 5
  8. template:
  9. metadata:
  10. labels:
  11. run: mytest
  12. spec:
  13. containers:
  14. - image: wangzan18/mytest:v1
  15. imagePullPolicy: IfNotPresent
  16. name: mytest

使用下面命令创建应用。

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

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

  1. kubectl label node node01.wzlinux.com disktype=ssd

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

  1. NAME STATUS ROLES AGE VERSION LABELS
  2. 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=
  3. 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
  4. 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:

  1. apiVersion: extensions/v1beta1
  2. kind: Deployment
  3. metadata:
  4. name: mytest
  5. namespace: default
  6. spec:
  7. replicas: 5
  8. template:
  9. metadata:
  10. labels:
  11. run: mytest
  12. spec:
  13. containers:
  14. - image: wangzan18/mytest:v1
  15. imagePullPolicy: IfNotPresent
  16. name: mytest
  17. nodeSelector:
  18. disktype: ssd

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

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

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

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

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

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

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

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

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

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

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

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

  1. kubectl delete node node02.wzlinux.com

node02 上面 reset。

  1. kubeadm reset

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

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

生成ca-cert-hash sha256的值。

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

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

Kubernetes 控制器之 Deployment 介绍(六)的更多相关文章

  1. Kubernetes的控制器之Deployment的定义

    Deploy 的控制器定义参数介绍 [root@master manifests]# kubectl explain deploy KIND: Deployment VERSION: extensio ...

  2. Kubernetes 控制器之 Service 讲解(七)

    一.背景介绍 我们这里准备三台机器,一台master,两台node,采用kubeadm的方式进行安装的,安装过程大家可以参照我之前的博文. IP 角色 版本 192.168.1.200 master ...

  3. kubernetes控制器之DaemonSet

    转载于https://blog.csdn.net/bbwangj/article/details/82867472 什么是 DaemonSet? DaemonSet 确保全部(或者一些)Node 上运 ...

  4. 十五、资源控制之Deployment

    资源控制器之Deployment Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationControlle ...

  5. Kubernetes---资源控制器之ReplicationController、ReplicaSet和Deployment

    1.ReplicationController和ReplicaSet介绍 RC(ReplicationController)主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数.即如果有容 ...

  6. 十六、资源控制器之DaemonSet

    资源控制器之DaemonSet DaemonSet 确保全部(或者一些) Node上运行一个 Pod 的副本,当有 Node 加入集群时,也会为他们新增一个 Pod,当有 Node 从集群移除时,这些 ...

  7. k8s运行容器之deployment(三)--技术流ken

    deployment 我们已经知道k8s是通过各种controller来管理pod的生命周期.为了满足不同业务场景,k8s开发了Deployment.ReplicaSet.DaemonSet.Stat ...

  8. Kubernetes 的层级命名空间介绍

    原文链接:https://fuckcloudnative.io/posts/introducing-hierarchical-namespaces/ 在单个 Kubernetes 集群上安全托管大量用 ...

  9. Kubernetes学习之路(六)之创建K8S应用

    一.Deployment的概念 K8S本身并不提供网络的功能,所以需要借助第三方网络插件进行部署K8S中的网络,以打通各个节点中容器的互通. POD,是K8S中的一个逻辑概念,K8S管理的是POD,一 ...

随机推荐

  1. sql null+字符=null

    哦,谢谢你,我还想问一个declare @temp varchar(10),@identity varchar(10),@sura varchar(10),@p int,@len int,@nod1  ...

  2. CodeForces - 95E: Lucky Country (多重背包)

    pro:给定N个点,M条边,现在你要给一些连通块加边,使得至少存在一个连通块的大小是由4和7组成的数字.问至少加边数量. sol: 看似一个很难的题目.  首先不要想太难了,还是应该想能不能用背包做. ...

  3. es6 添加事件监听

    //定义被侦听的目标对象 }; //定义处理程序 var interceptor = { set: function (receiver, property, value) { console.log ...

  4. python的numpy.array

    为什么要用numpy Python中提供了list容器,可以当作数组使用.但列表中的元素可以是任何对象,因此列表中保存的是对象的指针,这样一来,为了保存一个简单的列表[1,2,3].就需要三个指针和三 ...

  5. springboot的HTTPS配置

  6. zeptojs库

    一.简介 ①Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api. ②Zepto的设计目的是提供 jQuery 的类似的API,但并不是100%覆盖 ...

  7. xamarin/xamarin.forms 在锁屏电源唤醒时保持后台运行

    PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的. SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯 SCRE ...

  8. 14-ESP8266 SDK开发基础入门篇--上位机串口控制 Wi-Fi输出PWM的占空比,调节LED亮度,8266程序编写

    https://www.cnblogs.com/yangfengwu/p/11102026.html 首先规定下协议  ,CRC16就不加了哈,最后我会附上CRC16的计算程序,大家有兴趣自己加上 上 ...

  9. Codevs 1358 棋盘游戏(状压DP)

    1358 棋盘游戏 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master 题目描述 Description 这个游戏在一个有10*10个格子的棋盘上进行,初始时棋子位于左 ...

  10. 二八法则(The 80/20 Principle)

    二八法则的定义:在任何一组事物中,最重要的只占其中一小部分,约20%,其余80%尽管占多数,却是次要的. 二八法则的例子:社会上20%的人占有80%的社会财富 20%的工厂有80%的产出 80%的利润 ...