k8s运行容器之deployment(三)--技术流ken
deployment
我们已经知道k8s是通过各种controller来管理pod的生命周期。为了满足不同业务场景,k8s开发了Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等多种 Controller。我们首先学习最常用的 Deployment。
运行一个deployment
- [root@ken ~]# kubectl run httpd-ken1--generator=run-pod/v1 --image=httpd --replicas=
下面详细分析 Kubernetes 都做了些什么工作。
- [root@ken ~]# kubectl get deployment
- NAME READY UP-TO-DATE AVAILABLE AGE
- httpd-ken / 35m
kubectl get deplouyment命令可以查看 httpd-ken 的状态,输出显示两个副本正常运行。
接下来我们用 kubectl describe deployment 了解更详细的信息。
- [root@ken ~]# kubectl describe deployment httpd-ken
- Name: httpd-ken
- Namespace: default
- CreationTimestamp: Tue, Jan :: +
- Labels: run=httpd-ken
- Annotations: deployment.kubernetes.io/revision:
- Selector: run=httpd-ken
- Replicas: desired | updated | total | available | unavailable
- StrategyType: RollingUpdate
- MinReadySeconds:
- RollingUpdateStrategy: % max unavailable, % max surge
- Pod Template:
- Labels: run=httpd-ken
- Containers:
- httpd-ken:
- Image: httpd
- Port: <none>
- Host Port: <none>
- Environment: <none>
- Mounts: <none>
- Volumes: <none>
- Conditions:
- Type Status Reason
- ---- ------ ------
- Available True MinimumReplicasAvailable
- Progressing True NewReplicaSetAvailable
- OldReplicaSets: <none>
- NewReplicaSet: httpd-ken-5c949b96f (/ replicas created)
- Events:
- Type Reason Age From Message
- ---- ------ ---- ---- -------
- Normal ScalingReplicaSet 18m deployment-controller Scaled up replica set httpd-ken-5c949b96f to
大部分内容都是自解释的,我们重点看最下面部分。这里告诉我们创建了一个 ReplicaSet httpd-ken-5c949b96,Events 是 Deployment 的日志,记录了 ReplicaSet 的启动过程。
通过上面的分析,也验证了 Deployment 通过 ReplicaSet 来管理 Pod 的事实。接着我们将注意力切换到 httpd-ken-5c949b96,执行 kubectl describe replicaset:
- [root@ken ~]# kubectl get replicaset
- NAME DESIRED CURRENT READY AGE
- httpd-ken-5c949b96f 20m
两个副本已经就绪,用 kubectl describe replicaset 查看详细信息:
- [root@ken ~]# kubectl describe replicaset
- Name: httpd-ken-5c949b96f
- Namespace: default
- Selector: pod-template-hash=5c949b96f,run=httpd-ken
- Labels: pod-template-hash=5c949b96f
- run=httpd-ken
- Annotations: deployment.kubernetes.io/desired-replicas:
- deployment.kubernetes.io/max-replicas:
- deployment.kubernetes.io/revision:
- Controlled By: Deployment/httpd-ken
- Replicas: current / desired
- Pods Status: Running / Waiting / Succeeded / Failed
- Pod Template:
- Labels: pod-template-hash=5c949b96f
- run=httpd-ken
- Containers:
- httpd-ken:
- Image: httpd
- Port: <none>
- Host Port: <none>
- Environment: <none>
- Mounts: <none>
- Volumes: <none>
- Events:
- Type Reason Age From Message
- ---- ------ ---- ---- -------
- Normal SuccessfulCreate 20m replicaset-controller Created pod: httpd-ken-5c949b96f-twdsd
- Normal SuccessfulCreate 20m replicaset-controller Created pod: httpd-ken-5c949b96f-9cd52
Controlled By 指明此 ReplicaSet 是由 Deployment httpd-ken 创建。Events 记录了两个副本 Pod 的创建。接着我们来看 Pod,执行 kubectl get pod:
- [root@ken ~]# kubectl get pod
- NAME READY STATUS RESTARTS AGE
- httpd-ken-5c949b96f-9cd52 / Running 22m
- httpd-ken-5c949b96f-twdsd / Running 22m
两个副本 Pod 都处于 Running 状态,用 kubectl describe pod 查看更详细的信息:
- root@ken ~]# kubectl describe pod
- Name: httpd-ken-5c949b96f-9cd52
- Namespace: default
- Priority:
- PriorityClassName: <none>
- Node: host1/172.20.10.7
- Start Time: Tue, Jan :: +
- Labels: pod-template-hash=5c949b96f
- run=httpd-ken
- Annotations: <none>
- Status: Running
- IP: 10.244.1.3
- Controlled By: ReplicaSet/httpd-ken-5c949b96f
- Containers:
- httpd-ken:
- Container ID: docker://e59bda9941a16f20027c89a0d8fa8e17797b517f6f5461e905c0d29b57369dde
- Image: httpd
- Image ID: docker-pullable://httpd@sha256:44daa8e932a32ab6e50636d769ca9a60ad412124653707e5ed59c0209c72f9b3
- Port: <none>
- Host Port: <none>
- State: Running
- Started: Tue, Jan :: +
- Ready: True
- Restart Count:
- Environment: <none>
- Mounts:
- /var/run/secrets/kubernetes.io/serviceaccount from default-token-vb7lm (ro)
- Conditions:
- Type Status
- Initialized True
- Ready True
- ContainersReady True
- PodScheduled True
- Volumes:
- default-token-vb7lm:
- Type: Secret (a volume populated by a Secret)
- SecretName: default-token-vb7lm
- 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 23m default-scheduler Successfully assigned default/httpd-ken-5c949b96f-9cd52 to host1
- Normal Pulling 23m kubelet, host1 pulling image "httpd"
- Normal Pulled 22m kubelet, host1 Successfully pulled image "httpd"
- Normal Created 22m kubelet, host1 Created container
- Normal Started 22m kubelet, host1 Started container
Controlled By 指明此 Pod 是由 ReplicaSet httpd-ken-5c949b96f创建。Events 记录了 Pod 的启动过程。如果操作失败(比如 image 不存在),也能在这里查看到原因。
总结一下这个过程:
用户通过 kubectl 创建 Deployment。
Deployment 创建 ReplicaSet。
ReplicaSet 创建 Pod
也可以看出,对象的命名方式是:子对象的名字 = 父对象名字 + 随机字符串或数字。
命令vs配置文件
k8s支持两种创建资源的方式:
1.用 kubectl 命令直接创建,比如:
kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2
在命令行中通过参数指定资源的属性。
2. 通过配置文件和 kubectl apply 创建,要完成前面同样的工作,可执行命令:
kubectl apply -f nginx.yml
nginx.yml 的内容为:
资源的属性写在配置文件中,文件格式为 YAML。
下面对这两种方式进行比较。
基于命令的方式:
简单直观快捷,上手快。
适合临时测试或实验。
基于配置文件的方式:
配置文件描述了 What,即应用最终要达到的状态。
配置文件提供了创建资源的模板,能够重复部署。
可以像管理代码一样管理部署。
适合正式的、跨环境的、规模化部署。
这种方式要求熟悉配置文件的语法,有一定难度。
后面我们都将采用配置文件的方式,大家需要尽快熟悉和掌握。
kubectl apply 不但能够创建 Kubernetes 资源,也能对资源进行更新,非常方便。不过 Kubernets 还提供了几个类似的命令,例如 kubectl create、kubectl replace、kubectl edit 和 kubectl patch。
为避免造成不必要的困扰,我们会尽量只使用 kubectl apply,
此命令已经能够应对超过 90% 的场景,事半功倍。
deployment yaml
既然要用 YAML 配置文件部署应用,现在就很有必要了解一下 Deployment 的配置格式,其他 Controller(比如 DaemonSet)非常类似。
① apiVersion 是当前配置格式的版本。
先执行kubectl api-resources找到所有的资源
在执行命令 kubectl explain deploy即可获取到版本和类型信息
② kind 是要创建的资源类型,这里是 Deployment。
③ metadata 是该资源的元数据,name 是必需的元数据项。
④ spec 部分是该 Deployment 的规格说明。
⑤ replicas 指明副本数量,默认为 1。
⑥ template 定义 Pod 的模板,这是配置文件的重要部分。
⑦ metadata 定义 Pod 的元数据,至少要定义一个 label。label 的 key 和 value 可以任意指定。
⑧ spec 描述 Pod 的规格,此部分定义 Pod 中每一个容器的属性,name 和 image 是必需的。
此 nginx.yml 是一个最简单的 Deployment 配置文件,后面我们学习 Kubernetes 各项功能时会逐步丰富这个文件。
执行 kubectl apply -f nginx.yml:
- [root@ken ~]# kubectl apply -f nginx.yml
- deployment.extensions/nginx-deployment created
查看nginx-deployment各种资源
- [root@ken ~]# kubectl get deployment
- NAME READY UP-TO-DATE AVAILABLE AGE
- httpd-ken / 73m
- nginx-deployment / 107s
- [root@ken ~]# kubectl get replicaset
- NAME DESIRED CURRENT READY AGE
- httpd-ken-5c949b96f 54m
- nginx-deployment-65998d8886 111s
- [root@ken ~]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- httpd-ken-5c949b96f-9cd52 / Running 54m 10.244.1.3 host1 <none> <none>
- httpd-ken-5c949b96f-twdsd / Running 54m 10.244.2.3 host2 <none> <none>
- nginx-deployment-65998d8886-9qrrv / Running 2m4s 10.244.2.4 host2 <none> <none>
- nginx-deployment-65998d8886-vnbgt / Running 2m4s 10.244.1.4 host1 <none> <none>
Deployment、ReplicaSet、Pod 都已经就绪。如果要删除这些资源,执行 kubectl delete deployment nginx-deployment 或者 kubectl delete -f nginx.yml (编写的nginx.yml文件不会被删除)。
- [root@ken ~]# kubectl delete -f nginx.yml
- deployment.extensions "nginx-deployment" deleted
Scale Up/Down
伸缩(Scale Up/Down)是指在线增加或减少 Pod 的副本数。
Deployment nginx-deployment 初始是两个副本。
- [root@ken ~]# kubectl apply -f nginx.yml
- [root@ken ~]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx-deployment-65998d8886-5b5rc / Running 84s 10.244.1.5 host1 <none> <none>
- nginx-deployment-65998d8886-tnpcx / Running 84s 10.244.2.5 host2 <none> <none>
k8s-node1 和 k8s-node2 上各跑了一个副本。现在修改 nginx.yml,将副本改成 5 个。
再次执行kubectl apply
- [root@ken ~]# kubectl apply -f nginx.yml
- deployment.extensions/nginx-deployment configured
查看pod
- [root@ken ~]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx-deployment-65998d8886-4hfgp / Running 3m 10.244.1.7 host1 <none> <none>
- nginx-deployment-65998d8886-5b5rc / Running 5m48s 10.244.1.5 host1 <none> <none>
- nginx-deployment-65998d8886-btrsq / Running 3m 10.244.2.6 host2 <none> <none>
- nginx-deployment-65998d8886-tnpcx / Running 5m48s 10.244.2.5 host2 <none> <none>
- nginx-deployment-65998d8886-x4pbd / Running 3m 10.244.1.6 host1 <none> <none>
三个新副本被创建并调度到 k8s-node1 和 k8s-node2 上。
接下来修改配置文件,将副本数减少为 3 个,重新执行 kubectl apply:
- [root@ken ~]# kubectl apply -f nginx.yml
- deployment.extensions/nginx-deployment configured
- [root@ken ~]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx-deployment-65998d8886-5b5rc / Running 7m6s 10.244.1.5 host1 <none> <none>
- nginx-deployment-65998d8886-btrsq / Running 4m18s 10.244.2.6 host2 <none> <none>
- nginx-deployment-65998d8886-tnpcx / Running 7m6s 10.244.2.5 host2 <none> <none>
可以看到两个副本被删除,最终保留了 3 个副本。
模拟故障
上面我们有 3 个 nginx 副本分别运行在 k8s-node1 和 k8s-node2 上。现在模拟 k8s-node2 故障,关闭该节点(poweroff)。
首先查看节点
- [root@ken ~]# kubectl get node
- NAME STATUS ROLES AGE VERSION
- host1 Ready <none> 5h25m v1.13.2
- host2 NotReady <none> 5h43m v1.13.2
- ken Ready master 6h18m v1.13.2
发现host2状态为NotReady
等待一段时间,Kubernetes 会检查到 k8s-node2 不可用,将 k8s-node2 上的 Pod 标记为 Terminating状态,并在 k8s-node1 上新创建两个 Pod,维持总副本数为 3。
- [root@ken ~]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx-deployment-65998d8886-5b5rc / Running 16m 10.244.1.5 host1 <none> <none>
- nginx-deployment-65998d8886-8647d / Running 79s 10.244.1.8 host1 <none> <none>
- nginx-deployment-65998d8886-btrsq / Terminating 13m 10.244.2.6 host2 <none> <none>
- nginx-deployment-65998d8886-qp6jj / Running 79s 10.244.1.9 host1 <none> <none>
- nginx-deployment-65998d8886-tnpcx / Terminating 16m 10.244.2.5 host2 <none> <none>
当 k8s-node2 恢复后, Terminating的 Pod 会被删除,不过已经运行的 Pod 不会重新调度回 k8s-node2。
- [root@ken ~]# kubectl get node
- NAME STATUS ROLES AGE VERSION
- host1 Ready <none> 5h33m v1.13.2
- host2 Ready <none> 5h51m v1.13.2
- ken Ready master 6h26m v1.13.2
- [root@ken ~]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx-deployment-65998d8886-5b5rc / Running 19m 10.244.1.5 host1 <none> <none>
- nginx-deployment-65998d8886-8647d / Running 4m33s 10.244.1.8 host1 <none> <none>
- nginx-deployment-65998d8886-qp6jj / Running 4m33s 10.244.1.9 host1 <none> <none>
删除 nginx-deployment:
- [root@ken ~]# kubectl delete -f nginx.yml
- deployment.extensions "nginx-deployment" deleted
label 控制 Pod 的位置
默认配置下,Scheduler 会将 Pod 调度到所有可用的 Node。不过有些情况我们希望将 Pod 部署到指定的 Node,比如将有大量磁盘 I/O 的 Pod 部署到配置了 SSD 的 Node;或者 Pod 需要 GPU,需要运行在配置了 GPU 的节点上。
Kubernetes 是通过 label 来实现这个功能的。
label 是 key-value 对,各种资源都可以设置 label,灵活添加各种自定义属性。比如执行如下命令标注 k8s-node1 是配置了 SSD 的节点。
第一步:定义标签
disk为自定义字符串
- [root@ken ~]# kubectl label node host1 disk=ssd
第二步:查看标签
- [root@ken ~]# kubectl get node --show-labels
- NAME STATUS ROLES AGE VERSION LABELS
- host1 Ready <none> 8h v1.13.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disk=ssd,kubernetes.io/hostname=host1
- host2 Ready <none> 8h v1.13.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=host2
- ken Ready master 8h v1.13.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=ken,node-role.kubernetes.io/master=
disk=ssd 已经成功添加到 host1,除了 disk,Node 还有几个 Kubernetes 自己维护的 label。
第三步:配置nginx.yml
有了 disk 这个自定义 label,接下来就可以指定将 Pod 部署到 host1。编辑 nginx.yml:
在 Pod 模板的 spec 里通过 nodeSelector 指定将此 Pod 部署到具有 label disktype=ssd 的 Node 上。
注意:1. nodeSelector需要与containers位置保持一致
2. S必须大写
第四步:部署
部署 Deployment
- [root@ken ~]# kubectl apply -f nginx.yml
- deployment.extensions/nginx-deployment created
第五步:查看 Pod 的运行节点
- [root@ken ~]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx-deployment-5d8db4598d-2gdmz / ContainerCreating 102s <none> host1 <none> <none>
- nginx-deployment-5d8db4598d-cq55q / ContainerCreating 102s <none> host1 <none> <none>
- nginx-deployment-5d8db4598d-qjh4x / ContainerCreating 102s <none> host1 <none> <none>
全部 3个副本都运行在 host1 上,符合我们的预期。
要删除 label disktype,执行如下命令:
kubectl label node k8s-node1 disktype-
- 即删除。
- [root@ken ~]# kubectl label node host1 disk-
- node/host1 labeled
- [root@ken ~]# kubectl get node --show-labels
- NAME STATUS ROLES AGE VERSION LABELS
- host1 NotReady <none> 8h v1.13.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=host1
- host2 Ready <none> 8h v1.13.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=host2
- ken Ready master 9h v1.13.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=ken,node-role.kubernetes.io/master=
不过此时 Pod 并不会重新部署,依然在 host1 上运行。
- [root@ken ~]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx-deployment-5d8db4598d-2dbw9 / Running 39s 10.244.1.12 host1 <none> <none>
- nginx-deployment-5d8db4598d-4brh5 / Running 39s 10.244.1.11 host1 <none> <none>
- nginx-deployment-5d8db4598d-p87mj / Running 39s 10.244.1.13 host1 <none> <none>
除非在 nginx.yml 中删除 nodeSelector 设置,然后通过 kubectl apply 重新部署。
不需要删除之前的deployment,直接部署即可
Kubernetes 自己会删除之前的 Pod 并调度和运行新的 Pod。
- [root@ken ~]# kubectl apply -f nginx.yml
- [root@ken ~]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx-deployment-5d8db4598d-p87mj / Terminating 2m 10.244.1.13 host1 <none> <none>
- nginx-deployment-65998d8886-t5nmv / Running 7s 10.244.2.9 host2 <none> <none>
- nginx-deployment-65998d8886-wz7c2 / Running 4s 10.244.2.10 host2 <none> <none>
- nginx-deployment-65998d8886-xdlz4 / Running 6s 10.244.1.14 host1 <none> <none>
k8s运行容器之deployment(三)--技术流ken的更多相关文章
- k8s运行容器之deployment(三)
deployment 我们已经知道k8s是通过各种controller来管理pod的生命周期.为了满足不同业务场景,k8s开发了Deployment.ReplicaSet.DaemonSet.Stat ...
- k8s重要概念及部署k8s集群(一)--技术流ken
重要概念 1. cluster cluster是 计算.存储和网络资源的集合,k8s利用这些资源运行各种基于容器的应用. 2.master master是cluster的大脑,他的主要职责是调度,即决 ...
- k8s架构分析(二)--技术流ken
master节点 k8s的集群由master和node组成,节点上运行着若干k8s服务. master节点之上运行着的后台服务有kube-apiserver .kube-scheduler.kube- ...
- k8s运行容器之Job(四)--技术流ken
Job 容器按照持续运行的时间可分为两类:服务类容器和工作类容器. 服务类容器通常持续提供服务,需要一直运行,比如 http server,daemon 等.工作类容器则是一次性任务,比如批处理程序, ...
- k8s运行容器之Job(四)
Job 容器按照持续运行的时间可分为两类:服务类容器和工作类容器. 服务类容器通常持续提供服务,需要一直运行,比如 http server,daemon 等.工作类容器则是一次性任务,比如批处理程序, ...
- k8s运行容器之Job应用(6)
容器按照持续运行的时间可分为两类:服务类容器和工作类容器. 服务类容器通常持续提供服务,需要一直运行,比如 http server,daemon 等.工作类容器则是一次性任务,比如批处理程序,完成后容 ...
- k8s滚动更新(六)--技术流ken
实践 滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新.滚动更新的最大的好处是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性. 下面我们部署三副本应用, ...
- Redis主从复制、多实例、高可用(三)--技术流ken
Redis主从复制 在开始实现redis的高可用之前,首先来学习一下如何实现redis的主从复制,毕竟高可用也会依赖主从复制的技术. Redis的主从复制,可以实现一个主节点master可以有多个从节 ...
- k8s健康检查(七)--技术流ken
默认的健康检查 强大的自愈能力是 Kubernetes 这类容器编排引擎的一个重要特性.自愈的默认实现方式是自动重启发生故障的容器.除此之外,用户还可以利用 Liveness 和 Readiness ...
随机推荐
- [AtCoder3856]Ice Rink Game - 模拟
Problem Statement An adult game master and N children are playing a game on an ice rink. The game co ...
- yarn的工作原理
1.YARN 是什么? 从业界使用分布式系统的变化趋势和 hadoop 框架的长远发展来看,MapReduce的 JobTracker/TaskTracker 机制需要大规模的调整来修复它在可扩展性, ...
- 将DataRow拷贝到另一个DataRow
DataRow dr = dtPadFluid.Rows[gvPadFluid.FocusedRowHandle]; foreach (DataColumn dc in _dr.Table.Colum ...
- react-native 常用的一些插件
react-native 常用的一些插件 最近在做react-native的app,用到的一些好用的插件,在这儿记录一下 由于返回的后台内容是富文本编辑器Quill,返回的的是Delta对象,使用了q ...
- 实战深度学习OpenCV(三):视频实时canny边缘检测
#include <stdio.h> #include"opencv2/opencv.hpp" using namespace cv; int main() { Vid ...
- JQuery实现 图片上传
用到的文件,我都已经打包好了,自行下载: https://files.cnblogs.com/files/lguow/lib.rar 核心代码如下: <input type="hidd ...
- 使用Nginx做图片服务器时候,配置之后图片访问一直是 404问题解决
我的错误配置是: 服务器文件根地址: 想通过浏览器输入这个地址访问到图片: 但是会发现文件找不到会一直404,原因是根路径配置错误,来看下root路径原理: root 配置的意思是,会在root配置的 ...
- Node.js(day6)
初始化准备工作 初始化目录 nmp init -y 安装基本的第三方插件 express npm install express --save art-template npm install art ...
- [Swift]LeetCode167. 两数之和 II - 输入有序数组 | Two Sum II - Input array is sorted
Given an array of integers that is already sorted in ascending order, find two numbers such that the ...
- [Swift]LeetCode424. 替换后的最长重复字符 | Longest Repeating Character Replacement
Given a string that consists of only uppercase English letters, you can replace any letter in the st ...