Node的管理
Node的隔离与恢复
在硬件升级、硬件维护等情况下,我们需要将某些Node隔离,使其脱离Kubernetes集群的调度范围。Kubernetes提供了一种机制,既可以将Node纳入调度范围,也可以将Node脱离调度范围。
创建配置文件unschedule_node.yaml,在spec部分指定unschedulable为true:
1
2
3
4
5
6
7
8
9 1apiVersion: v1
2kind: Node
3metadata:
4 name: k8s-node-1
5 labels:
6 kubernetes.io/hostname:k8s-node-1
7spec:
8 unschedulable: true
9
通过kubectl replace 命令完成对Node状态的修改
1
2 1kubectl replace -f unschedule_node.yaml
2
查看Node的状态,可以观察到在Node的状态中增加了一项SchedulingDisabled:
1
2 1kubectl get nodes
2
这样,对于后续创建的Pod,系统将不会再向该Node进行调度。
也可以不使用配置文件,直接使用kubectl patch命令完成:
1
2 1kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable": true}}'
2
需要注意的是,将某个Node脱离调度范围时,在其上运行的Pod并不会自动停止,管理员需要手动停止在该Node上运行的Pod。
同样,如果需要将某个Node重新纳入集群调度范围,则将unschedulable设置为false,再次执行kubectl replace或kubectl patch命令就能恢复系统对该Node的调度。
另外,使用kubectl的子命令cordon和uncordon也可以实现将Node进行隔离调度和恢复调度操作。
例如,使用kubectl cordon <node_name>对某个Node进行隔离调度操作:
1
2 1kubectl cordon k8s-node-1
2
使用 kubectl uncordon <node_name>对某个Node进行恢复调度操作:
1
2 1kubectl uncordon k8s-node-1
2
Node的扩容
在实际生产系统中经常会出现服务器容量不足的情况,这时就需要购买新的服务器,然后将应用系统进行水平扩展来完成对系统的扩容。
在Kubernetes集群中,一个新Node的加入是非常简单的。在新的Node上安装Docker、kubelet和kube-proxy服务,然后配置kubelet和kube-proxy的启动参数,将Master URL指定为当前Kubernetes集群Master的地址,最后启动这些服务。通过kubelet默认的自动注册机制,新的Node将会自动加入现有的Kubernetes集群中。
Kubernetes Master在接受了新Node的注册之后,会自动将其纳入当前集群的调度范围,之后创建容器时,就可以对新的Node进行调度了。
通过这种机制,Kubernetes实现了集群中Node的扩容。
更新资源对象的Label
Label是用户可灵活定义的对象属性,对于正在运行的资源对象,我们随时可以通过kubectl label命令进行增加、修改、删除等操作。
例如,要给已创建的Pod “redis-master-bobr0”添加一个标签role=backend:
1
2 1kubectl label pod redis-master-bobr0 role=backend
2
查看该Pod的Label:
1
2 1kubectl get pods -Lrole
2
删除一个Label时,只需在命令行最后指定Label的key名并与一个减号相连即可:
1
2 1kubectl label pod redis-master-bobr0 role-
2
在修改一个Label的值时,需要加上–overwrite参数:
1
2 1kubectl label pod redis-master-bobr0 role=master --overwrite
2
Namespace:集群环境共享与隔离
在一个组织内部,不同的工作组可以在同一个Kubernetes集群中工作,Kubernetes通过命名空间和Context的设置对不同的工作组进行区分,使得它们既可以共享同一个Kubernetes集群的服务,也能够互不干扰。
假设在我们的组织中有两个工作组:开发组和生产运维组。开发组在Kubernetes集群中需要不断创建、修改、删除各种Pod、RC、Service等资源对象,以便实现敏捷开发。生产运维组则需要使用严格的权限设置来确保生产系统中的Pod、RC、Service处于正常运行状态且不会被误操作。
创建Namespace
为了在Kubernetes集群中实现这两个分组,首先需要创建两个命名空间:
1
2
3
4
5
6
7
8
9
10
11 1---
2apiVersion: v1
3kind: Namespace
4metadata:
5 name: development
6---
7apiVersion: v1
8kind: Namespace
9metadata:
10 name: production
11
使用kubectl create 命令完成命名空间的创建:
1
2 1kubectl create -f namespace-de-pro.yaml
2
查看系统中的命名空间:
1
2
3 1kubectl get namespaces
2kubectl get ns
3
定义Context(运行环境)
接下来,需要为这两个工作组分别定义一个 Context,即运行环境。这个运行环境将属于某个特定的命名空间。
通过kubectl config set-context命令定义Context,并将Context置于之前创建的命名空间中:
1
2
3
4 1# kubectl config set-cluster kubernetes-cluster --server=https://192.168.1.128:8080
2# kubectl config set-context ctx-dev --namespace=development --cluster=kubernetes-cluster --user=dev
3# kubectl config set-context ctx-prod --namespace=production --cluster=kubernetes-cluster --user=prod
4
使用kubectl config view命令查看已定义的Context:
1
2 1kubectl config view
2
注意,通过kubectl config命令在${HOME}/.kube目录下生成了一个名为config的文件,文件的内容为以kubectl config view命令查看到的内容。所以,也可以通过手工编辑该文件的方式来设置Context。
设置工作组在特定Context环境下工作
使用kubectl config use-context <context_name>命令设置当前运行环境。
下面的命令将把当前运行环境设置为ctx-dev:
1
2 1kubectl config use-context ctx-dev
2
运行这个命令后,当前的运行环境被设置为开发组所需的环境。之后的所有操作都将在名为development的命名空间中完成。
现在,以redis-slave RC为例创建两个Pod:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 1apiVersion: v1
2kind: ReplicationController
3metadata:
4 name: redis-slave
5 labels:
6 name: redis-slave
7spec:
8 replicas: 2
9 selector:
10 name: redis-slave
11 template:
12 metadata:
13 labels:
14 name: redis-slave
15 spec:
16 containser:
17 - name: slave
18 image: kubeguide/guestbook-redis-slave
19 ports:
20 - containerPort: 6379
21
查看创建好的Pod:
1
2 1kubectl get pods
2
可以看到容器被正确创建并运行起来了。而且,由于当前运行环境是ctx-dev,所以不会影响生产运维组的工作。
切换到生产运维组的运行环境查看RC和Pod:
1
2
3
4 1# kubectl config use-context ctx-prod
2# kubectl get rc
3# kubectl get pods
4
结果为空,说明看不到开发组创建的RC和Pod。
现在也为生产运维组创建两个redis-slave的Pod,查看创建好的Pod。可以看到容器被正确创建并运行起来了,并且当前运行环境是ctx-prod,也不会影响开发组的工作。
至此,我们为两个工作组分别设置了两个运行环境,设置好当前运行环境时,各工作组之间的工作将不会相互干扰,并且都能在同一个Kubernetes集群中同时工作。
小结:
本节的内容到此结束,谢谢大家的浏览!
记得自己动手做一下例子哦。有问题请在下方留言!