(1)Node的隔离与恢复

在硬件升级、硬件维护等情况下,需要将某些Node隔离。使用kubectl cordon <node_name>命令可禁止Pod调度到该节点上,在其上运行的Pod并不会自动停止,管理员需要手动停止在该Node上运行的Pod。

[root@master ~]# kubectl cordon node

查看Node的状态,可以观察到在node的状态中增加了一项SchedulingDisabled,对于后续创建的Pod,系统将不会再向该Node进行调度。

[root@master ~]# kubectl get nodes

通过kubectl uncordon命令可完成对Node的恢复。

[root@master ~]# kubectl uncordon node
[root@master ~]# kubectl get nodes

可以看到Node节点已恢复调度,允许Pod调度到该节点上。
通过kubectl drain 命令可实现对node节点的驱逐,该命令会删除该节点上的所有Pod(DaemonSet除外),在其他Node上重新启动它们。

(2)Pod动态扩容和缩放

在实际生产系统中,经常会遇到某个服务需要扩容的场景,也可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的场景。此时可以利用kubectl scale deployment命令来完成这些任务。
以Nginx Deployment为例,已定义的最初副本数量为1。

[root@master ~]# kubectl run nginx --image=10.18.4.10/library/nginx:latest
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 created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-ccb467dc5-jlr4c 1/1 Running 0 40s

通过执行下面的命令将Nginx Deployment控制的Pod副本数量从初始的1更新为5。

[root@master ~]# kubectl scale deployment nginx --replicas=5
deployment.extensions/nginx scaled

执行kubectl get pods命令来验证Pod的副本数量增加到5。

[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-ccb467dc5-2f6n2 1/1 Running 0 34s
......

将–replicas设置为比当前Pod副本数量更小的数字,系统将会“杀掉”一些运行中的Pod,即可实现应用集群缩容。

[root@master ~]# kubectl scale deployment nginx --replicas=2
deployment.extensions/nginx scaled
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-ccb467dc5-bl4jp 1/1 Running 0 2m50s
nginx-ccb467dc5-jlr4c 1/1 Running 0 5m21s

(3)将Pod调度到指定的Node

Kubernetes的Scheduler服务(kube-scheduler进程)负责实现Pod的调度,整个调度过程通过执行一系列复杂的算法最终为每个Pod计算出一个最佳的目标节点,这一过程是自动完成的,用户无法知道Pod最终会被调度到哪个节点上。有时可能需要将Pod调度到一个指定的Node上。此时,可以通过Node的标签(Label)和Pod的nodeSelector属性相匹配,来达到上述目的。
Label(标签)作为用户可灵活定义的对象属性,在已创建的对象上,仍然可以随时通过kubectl label命令对其进行增加、修改、删除等操作。使用kubectl label给node打标签的用法如下:

# kubectl label nodes <node-name> <label-key>=<label-value>

下面的示例,为node打上一个project=gcxt的标签。

[root@master ~]# kubectl label nodes node project=gcxt
node/node labeled

如果想删除Label,只需要在命令行最后指定Label的key名,并加一个减号即可。

[root@master ~]# kubectl label node node project-
node/node labeled

在Pod中加入nodeSelector定义,示例如下。

[root@master ~]# cat nginx.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: memcached-gcxt
labels:
name: memcached-gcxt
spec:
replicas: 1
selector:
name: memcached-gcxt
template:
metadata:
labels:
name: memcached-gcxt
spec:
containers:
- name: memcached-gcxt
image: memcached
command:
- memcached
- -m 64
ports:
- containerPort: 11211
nodeSelector:
project: gcxt

运行kubectl create -f命令创建Pod,scheduler就会将该Pod调度到拥有project=gcxt标签的Node上去。

[root@master ~]# kubectl create -f nginx.yaml
replicationcontroller/memcached-gcxt created

查看Pod。

[root@master ~]# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
memcached-gcxt-hdt5x 1/1 Running 0 14s 10.24.9.2 node <none> <none>

可以看到,Pod已成功调度到指定的Node节点。
这种基于Label标签的调度方式灵活性很高,比如,可以把一组Node分别贴上“开发环境”、“测试环境”、“生产环境”这3组标签中的一种,此时一个Kubernetes集群就承载了3个环境,这将大大提高开发效率。
注意:如果指定了Pod的nodeSelector条件,且集群中不存在包含相应标签的Node时,即使还有其他可供调度的Node,这个Pod也最终会调度失败。

(4)应用滚动升级

当集群中的某个服务需要升级时,需要停止目前与该服务相关的所有Pod,然后重新拉取镜像并启动。如果集群规模比较大,这个工作就变成了一个挑战。如果采取先全部停止,然后逐步升级的方式,会导致较长时间的服务不可用。Kubernetes提供了rolling-update(滚动升级)功能来解决上述问题。
滚动升级通过执行kubectl rolling-update命令一键完成,该命令创建了一个新的Deployment,然后自动控制旧的Deployment中的Pod副本数量逐渐减少到0,同时新的Deployment中的Pod副本数量从0逐步增加到目标值,最终实现了Pod的升级。
注意:系统要求新的Deployment需要与旧的Deployment在相同的命名空间(Namespace)内,即不能把别人的资产偷偷转移到自家名下。
下面的示例在第一次部署时使用httpd:2.2.31,然后使用滚动升级更新到httpd:2.2.32。
定义httpd.yaml文件。

[root@master ~]# cat httpd.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: httpd
spec:
replicas: 3
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: 10.18.4.10/library/httpd:2.2.31
ports:
- containerPort: 80

启动Deployment。

[root@master ~]# kubectl create -f httpd.yaml
deployment.apps/httpd created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-5ddb558f47-46tf5 1/1 Running 0 49s
httpd-5ddb558f47-5dg96 1/1 Running 0 49s
httpd-5ddb558f47-672sk 1/1 Running 0 49s

查看Deployment。

[root@master ~]# kubectl get deployments httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 3/3 3 3 93s httpd httpd:2.2.31 run=httpd

可以看到,IMAGES为httpd:2.2.31。
把配置文件中的httpd:2.2.31改为httpd:2.2.32,再次启动。

[root@master ~]# cat httpd.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: httpd
spec:
replicas: 3
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: 10.18.4.10/library/httpd:2.2.32 //将2.2.31更改为2.2.32
ports:
- containerPort: 80
-
[root@master ~]# kubectl apply -f httpd.yaml
deployment.apps/httpd configured

再次查看Deployment。

[root@master ~]# kubectl get deployments httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 3/3 3 3 7m53s httpd httpd:2.2.32 run=httpd

查看Deployment的详细信息。

[root@master ~]# kubectl describe deployment httpd
…...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 22m deployment-controller Scaled up replica set httpd-5ddb558f47 to 3
Normal ScalingReplicaSet 15m deployment-controller Scaled up replica set httpd-8bdffc6d8 to 1
Normal ScalingReplicaSet 14m deployment-controller Scaled down replica set httpd-5ddb558f47 to 2
Normal ScalingReplicaSet 14m deployment-controller Scaled up replica set httpd-8bdffc6d8 to 2
Normal ScalingReplicaSet 14m deployment-controller Scaled down replica set httpd-5ddb558f47 to 1
Normal ScalingReplicaSet 14m deployment-controller Scaled up replica set httpd-8bdffc6d8 to 3
Normal ScalingReplicaSet 13m deployment-controller Scaled down replica set httpd-5ddb558f47 to 0

上面的日志信息就描述了滚动升级的过程:
① 启动一个新版Pod。
② 把旧版Pod数量降为2。
③ 再启动一个新版,数量变为2。
④ 把旧版Pod数量降为1。
⑤ 再启动一个新版,数量变为3。
⑥ 把旧版Pod数量降为0。
这就是滚动的意思,始终保持副本数量为3,控制新旧Pod的交替,实现了无缝升级。
kubectl apply每次更新应用时,kubernetes都会记录下当前的配置,保存为一个revision,这样就可以回滚到某个特定的版本。
创建3个配置文件,内容中唯一不同的就是镜像的版本号。
httpd.v1.yaml:

[root@master ~]# cat httpd.v1.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: httpd
spec:
revisionHistoryLimit: 10 # 指定保留最近的几个revision
replicas: 3
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: 10.18.4.10/library/httpd:2.2.16
ports:
- containerPort: 80
httpd.v2.yaml:
[root@master ~]# cat httpd.v2.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: httpd
spec:
revisionHistoryLimit: 10 # 指定保留最近的几个revision
replicas: 3
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: 10.18.4.10/library/httpd:2.2.17
ports:
- containerPort: 80
httpd.v3.yaml:
[root@master ~]# cat httpd.v3.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: httpd
spec:
revisionHistoryLimit: 10 # 指定保留最近的几个revision
replicas: 3
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: 10.18.4.10/library/httpd:2.2.18
ports:
- containerPort: 80

部署Deployment。

[root@master ~]# kubectl apply -f httpd.v1.yaml --record
deployment.apps/httpd configured
[root@master ~]# kubectl apply -f httpd.v2.yaml --record
deployment.apps/httpd configured
[root@master ~]# kubectl apply -f httpd.v3.yaml --record
deployment.apps/httpd configured

–record的作用是将当前命令记录到revision中,可以知道每个revision对应的是哪个配置文件。
查看Deployment。

[root@master ~]# kubectl get deployments -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 3/3 1 3 31m httpd 10.18.4.10/library/httpd:2.2.18 run=httpd

查看revision历史记录。

[root@master ~]# kubectl rollout history deployment httpd
deployment.extensions/httpd
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 kubectl apply --filename=httpd.v1.yaml --record=true
4 kubectl apply --filename=httpd.v2.yaml --record=true
5 kubectl apply --filename=httpd.v3.yaml --record=true

CHANGE-CAUSE即-record的结果。
执行如下操作,回滚到指定版本revision 1。

[root@master ~]# kubectl rollout undo deployment httpd --to-revision=1
deployment.extensions/httpd rolled back
[root@master ~]# kubectl get deployments -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 3/3 3 3 35m httpd 10.18.4.10/library/httpd:2.2.31 run=httpd

再次查看Deployment可以看到httpd版本已经回退了。
查看revision历史记录,可以看到revision记录也发生了变化。

[root@master ~]# kubectl rollout history deployment httpd
deployment.extensions/httpd
......

【云原生 · Kubernetes】Kubernetes运维的更多相关文章

  1. 真正云原生的智能运维体系,阿里云发布ECS自动化运维套件

    云计算的发展,推动了自动化运维.DevOps.AIOps 等趋势的兴起,在业务快速变化的今天,企业希望通过一套自动化运维的专家系统提高运维效率,为业务提供支撑. 传统的方式下,打造一套成熟的 DevO ...

  2. 不看好运维竖井产品模式,优云打造融合化运维PaaS平台

    2018年1月13号中国双态运维用户大会上,优云软件总裁刘东海接受了36Kr记者的专访,期间谈到了新时代下的企业运维模式,新兴技术和传统运维的融合以及优云未来的发展方向等问题.以下为访谈实录: 优云软 ...

  3. 云时代IDC自动化运维的几大神器

    云时代IDC自动化运维的几大神器 2016年09月18日 10:27:41 天府云创 阅读数:1715   版权声明:本文为EnweiTech原创文章,未经博主允许不得转载. https://blog ...

  4. 云原生应用 Kubernetes 监控与弹性实践

    前言 云原生应用的设计理念已经被越来越多的开发者接受与认可,而Kubernetes做为云原生的标准接口实现,已经成为了整个stack的中心,云服务的能力可以通过Cloud Provider.CRD C ...

  5. 从零搭建云原生技术kubernetes(K8S)环境-通过kubesPhere的AllInOne方式

    前言 k8s云原生搭建,步骤有点多,但通过kubesphere,可以快速搭建k8s环境,同时有一个以 Kubernetes 为内核的云原生分布式操作系统-kubesphere,本文将从零开始进行kub ...

  6. 云时代的IT运维面临将会有哪些变化

    导读 每一次IT系统的转型,运维系统和业务保障都是最艰难的部分.在当前企业IT系统向云架构转型的时刻,运维系统再一次面临着新的挑战.所以在数据中心运维的时候,运维人员应该注意哪些问题? 在云计算时代, ...

  7. 优云亮相GOPS2017全球运维大会 “黑科技”获全场最高关注

    2017年4月21日,GOPS――2017全球运维大会于深圳・圣淘沙酒店拉开帷幕.GOPS全球运维大会由高效运维社区(GreatOPS)和开放运维联盟(OOPSA)联合主办,由工信部信通院数据中心联盟 ...

  8. 阿里云“网红&quot;运维工程师白金:做一个平凡的圆梦人

    他是阿里云的一位 P8 运维专家,却很有野心得给自己取花名“辟拾(P10)”:他没有华丽的履历,仅凭着 26 年的热爱与坚持,一步一个脚印踏出了属于自己的技术逆袭之路:他爱好清奇,练就了能在 20 秒 ...

  9. 京东云开发者|IoT运维 - 如何部署一套高可用K8S集群

    环境 准备工作 配置ansible(deploy 主机执行) # ssh-keygen # for i in 192.168.3.{21..28}; do ssh-copy-id -i ~/.ssh/ ...

  10. ubuntu 阿里云 常出问题 运维工作日志

    一.2015-8.26(数据库 error—28) tmp文件临时数据写入不了----解决办法 1.查看临时文件 ls -l 找到了 2.由此可以查看得出来tmp文件有的权限是有的 3.查看tmp 存 ...

随机推荐

  1. 用Python实现广度优先搜索

    图是一种善于处理关系型数据的数据结构,使用它可以很轻松地表示数据之间是如何关联的 图的实现形式有很多,最简单的方法之一就是用散列表 背景 图有两种经典的遍历方式:广度优先搜索和深度优先搜索.两者是相似 ...

  2. uniapp小程序新版授权登录

    1.授权按钮: <view> <button class='login-btn' type='primary' @click="bindGetUserInfo"& ...

  3. haodoop概念总结

    大数据部门组织结构 Hadoop的优势(4高) 高可靠性:Hadoop底层维护多个数据副本 高扩展性:在集群间分配任务数据,可方便的扩展 高效性:在MapReduce的思想下,Hadoop时并行工作的 ...

  4. ImGUI 1.87 绘制D3D外部菜单

    ImGUI 它是与平台无关的C++轻量级跨平台图形界面库,没有任何第三方依赖,可以将ImGUI的源码直接加到项目中使用,该框架通常会配合特定的D3Dx9等图形开发工具包一起使用,ImGUI常用来实现进 ...

  5. Tubian系统无法打开Android子系统的解决方法

    打开Konsole,Konsole在程序菜单(左下角Logo)-系统中 输入: sudo nano /var/lib/waydroid/waydroid.cfg 回车 按方向键,把光标移动到[prop ...

  6. 几个Caller-特性的妙用

    System.Runtime.CompilerServices命名空间下有4个以"Caller"为前缀命名的Attribute,我们可以将它标注到方法参数上自动获取当前调用上下文的 ...

  7. 它让你1小时精通RabbitMQ消息队列(新增死信处理)

    支持.NET/.NET Framework/.NET Core RabbitMQ作为一款主流的消息队列工具早已广受欢迎.相比于其它的MQ工具,RabbitMQ支持的语言更多.功能更完善. 本文提供一种 ...

  8. pthread_mutex_t & pthread_cond_t 总结

    pthread_mutex_t & pthread_cond_t 总结 一.多线程并发 1.1 多线程并发引起的问题 我们先来看如下代码: #include <stdio.h> # ...

  9. Java I/O(3):NIO中的Buffer

    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 之前在调用Channel的代码中,使用了一个名叫ByteBuffer类,它是Buffer的子类.这个叫Buffer的类是专门用来解决高速设备与低 ...

  10. Hyperf使用ElasticSearch记录

    Hyperf 安装 Elasticsearch 协程客户端 hyperf/elasticsearch 主要为 elasticsearch-php 进行了客户端对象创建的工厂类封装,elasticsea ...