Kubernetes Cookbook 编程指南 中文版教程
创建时间:2018-12-07  访问量:3673  7  0

Kubernetes Cookbook 编程指南 中文版教程

副本控制器(Replication Controller)的使用

副本控制器是Kubernetes中控制pod副本API对象的术语。这个概念就是要能够控制一组Pod的行为。这个副本控制器就是要保证这些Pod要始终运行在用户指定的一个数量。如果副本控制器中的一些pod崩溃终止了,系统将自动在那些健康的Node节点上使用原始的配置重启创建这些Pod,以保持确定数量的进程持续运行。根据这个特性,不管你是否需要Pod的副本,你总是可以使用副本控制器保护这些Pods以自动恢复。在本节,你将学习如何通过使用副本控制器来管理你的Pod:

副本控制器通常是控制应用层。正如你上面图片所示,我们运行一个副本控制器运行三个Pod副本。具体机制如下:

  • Master节点中有一个叫作Controller Manager的守护进程,它维护着资源运行在一个期望的状态,例如,上面图片中副本控制器的期望状态就是要有三个Pod副本。

  • Master中的调度器的守护进程负责分配任务到健康的节点中。

  • 副本控制的选择器用来决定它包含了哪些Pod。如果Pod的标签键值对包含副本控制器选择器中的所有选项,则此Pod属性于这个副本控制器。正如你将看到的,前面图片显示了有三个Pod在副本控制器的管理之中。因为有着不同次版本号(Pod2)的选择器包含了project和role标签,它仍名是副本成员之一。

开始

当我们安装了Kubernetes客户端软件包的时候,我们就在Kubernetes master中演示了副本控制器的管理。请首先登录到Master节点并确保你的环境可以创建副本控制器。

从Master节点创建副本控制器的评估

您可以通过检查以下项目来验证您的Kubernetes master是否实际可用: 检查守护进程是否正在运行。Master节点中应该有两个正在工作的守护进程:apiserver,scheduler和controller-manager。 检查kubectl命令是否存在并且是可以工作的。尝试运行命令kubectl get componentstatuses或者kubectl get cs,你不仅可以验证组件的状态还可以验证kubectl的可行性。 检查Node节点是否准备工作。你可以通过 kubectl get nodes 命令检查他们的状态。 假使上述有些项是无效的,请参考第1章,构建你自己的Kubernetes以查看合适安装指南。

如何去做...

可以直接通过CLI创建副本控制器,或者通过一个模板文件来创建。在本节我们将描述前者的解决方案。对于模板创建,请参考第3章,操作配置文件中的玩转容器这一小节。

 

创建一个副本控制器

为了创建副本控制器,我们在kubectl命令后使用run子命令。命令的基本形式如下所示:

// kubectl run <REPLICATION CONTROLLER NAME> --images=<IMAGE NAME>
[OPTIONAL_FLAGS]
# kubectl run my-first-rc --image=nginx
CONTROLLER 		CONTAINER(S) 	IMAGE(S) 	SELECTOR 			REPLICAS
my-first-rc 	my-first-rc 	nginx 		run=my-first-rc 	1

这个简单的命令就是通过Docker Hub(https://hub.docker.com)上的nginx镜像来创建一个副本控制器。名称 my-first-rc必须在所有副本控制器中保存唯一。您可以结合更多的选项标记,以创建特定的副本控制器:

-Flag=[Default Value] Description Example
--replicas=1 Pod副本数量 --replicas=3
--port=-1 容器暴露的端口 --port=80
--hostport=-1 映射容器的主机端口。使用这个选项标记须保证,你不能在一个Node节点上创建多个Pod副本,以避免端口冲突。 --hostport=8080
--labels="" Pod标签的键值对。每个键值对用逗号分隔 --labels="ProductName=HappyCloud, ProductionState=staging, ProjectOwner=Amy"
--command[=false] 在容器启动之后,通过此选项运行一个不同的命令。两个虚线附加在选项后面作以进行分隔命令内容。 --command -- /myapp/run.py -o logfile
--env=[] 在容器中设置环境变量。这个选项可以单独使用多次。 --env="USERNAME=amy" -- env="PASSWD=pa$$w0rd"
--overrides="" 使用这个选项以JSON格式来覆盖系统中的通用对像。JSON值是使用一个单引号包裹双引号。apiVersion字段是必须的。 --overrides='{"apiVersion"": "v1"}'
--limits="" 容器中资源使用上限。你可以指定可以使用多少CPU或内存。CPU单元核数格式为NUMBERm。m表示milli(10-3)。内存单元是字节。还请检查--requests。 --limits="cpu=1000m,memory=512Mi"
--requests="" 容器中资源的最少需求。这个值的规则与--limits相同。 --requests="cpu=250m,memory=256Mi"
--dry-run[=false] 显示对象配置,而无需将其发送出去创建。 --dry-run
--attach[=false] 对于副本控制器,终端将附加到其中一个副本,并查看来自程序的运行时日志。默认情况下是在pod中附加第一个容器,与Dockers附加的方式相同。系统中的一些日志显示容器的挂起状态 --attach
-i,--stdin[=false] 启用容器的交互模式。副本必须是1。 -i
--tty=[false] 分配一个tty(新的控制终端)到每个容器。你必须使用-i或--stdin开启交互模式。 -tty

子命令run黙认将创建一个副本控制器,因为--restart选项总是预设的,这意味着生成的对象将始终被触发并运行,以满足副本控制器的所需数量。

例如,你可以运行一个副本控制器,然后添加新的特征或修改配置:

// Run a replication controller with some flags for Nginx nodes. Try to
verify the settings with "--dry-run" first!
# kubectl run nginx-rc-test --image=nginx --labels="Owner=Amy,ProductionState=test" --replicas=2 --port=80 --dry-run
CONTROLLER 		CONTAINER(S) 	IMAGE(S) 	SELECTOR 	REPLICAS
nginx-rc-test 	nginx-rc-test 	nginx 	Owner=Amy,ProductionState=test 2

// Send out the request
# kubectl run nginx-rc --image=nginx --labels="Owner=Amy,ProductionState=test" --replicas=2 --port=80

// Try to override container name while generating, which name is the same as the name of replication controller in default
# kubectl run nginx-rc-override --image=nginx --overrides='{"apiVersion":"v1","spec":{"template":{"spec": {"containers":[{"name": "k8snginx","image":"nginx"}]}}}}'
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
nginx-rc-override k8s-nginx nginx run=nginx-rc-override 1

//Interact with container after create a pod in replication controller
# kubectl run nginx-bash --image=nginx --tty -i --command -- /bin/bash
Waiting for pod to be scheduled
Waiting for pod default/nginx-bash-916y6 to be running, status is
Running, pod ready: false
Waiting for pod default/nginx-bash-916y6 to be running, status is
Running, pod ready: false
ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@nginx-bash-916y6:/#

我们创建一个副本控制器之后,子命令get与describe可以帮助我们捕获信息和Pod的状态。在Kubernetes CLI中,我们通常使用简写的rc表示资源类型,而不是完整的replication controller名称:

首先,我们可以检查系统中的副本控制器:

// Use subcommand "get" to list replication controllers
# kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) 	SELECTOR 		REPLICAS 	AGE
check-rc-1 check-rc-1 	nginx 		run=check-rc-1 	5 			7m
check-rc-2 check-rc-2 	nginx 		app=nginx 		2 			6m

如上所示,特殊的列是SELECTOR与REPLICAS。选择器selector必须是Pod的标签,它标识着这些Pod是由哪个副本控制器控制。当使用kubectl run命令创建副本控制器时,我们可以通过 --labels 选项标签来指示selector选择器。由CLI通过 run=<REPLICATION CONTROLLER NAME>的形式创建的创建控制器会黙认分配一个Selector选择器:

// We can also get status of pod through selector/labels
# kubectl get pod -l app=nginx
NAME 				READY 	STATUS 		RESTARTS 	AGE
check-rc-2-95851 	1/1 	Running 	0 			6m
check-rc-2-mjezz 	1/1 	Running 	0 			6m

而且,子命令describe会帮助用户获取资料的详细项和日志:

# kubectl describe rc check-rc-2
Name: check-rc-2
Namespace: default
Image(s): nginx
Selector: app=nginx
Labels: app=nginx
Replicas: 2 current / 2 desired
Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed
No volumes.
Events:
FirstSeen LastSeen Count From SubobjectPath Reason
Message
───────── ──────── ───── ──── ───────────── ──────
───────
6m 6m 1 {replication-controller } SuccessfulCreate
Created pod: check-rc-2-95851
6m 6m 1 {replication-controller } SuccessfulCreate Created
pod: check-rc-2-mjezz

改变一个副本控制器的配置

诸如edit、patch和replace这些子命令可以帮助更新活动的副本控制器。所有这三个命令都是通地配置文件来修改设置的。这里我们仅仅以edit子命令为例说明:

子命令edit使用户通过编辑器修改资源配置。尝试通过kubectl edit rc/<REPLICATION CONTROLLER NAME>命令(来改变其它资源类型,你可以改变rc,例如,po,svc,ns)更新你的副本控制器。你可以通过YAML配置文件访问这些配置,除了资源类型和资源名称。可以看一下第3章的操作配置文件,参考玩转容器这一节,并尝试改成其它值试试:

// Try to update your by subcommand edit
# kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR      REPLICAS AGE
test-edit  test-edit    nginx    run=test-edit 1        5m

# kubectl edit rc/test-edit
replicationcontroller "test-edit" edited

# kubectl get rc
CONTROLLER 	CONTAINER(S) IMAGE(S) SELECTOR 				   REPLICAS AGE
test-edit 	nginx-rc 	 nginx 	  app=nginx,run=after-edit 3        7m

删除一个副本控制器

为了从系统中删除副本控制器,可以依赖于子命令delete。类似的子命令stop不赞成使用,并由delete代替,因此我们在这里介绍delete。当我们使用delete删除资源时,它强制删除目标对象,同时忽略目标对象的任何请求:

// 我们想要删除的副本控制器有5个Pod副本
# kubectl get rc
CONTROLLER  CONTAINER(S) IMAGE(S) SELECTOR        REPLICAS AGE
test-delete test-delete  nginx    run=test-delete 5        19s
# kubectl get pod
NAME 				READY 	STATUS  RESTARTS AGE
test-delete-g4xyy 	1/1 	Running 0 		 34s
test-delete-px9z6 	1/1 	Running 0 		 34s
test-delete-vctnk 	1/1 	Running 0 		 34s
test-delete-vsikc 	1/1 	Running 0 		 34s
test-delete-ye07h 	1/1 	Running 0 		 34s

// timing the response of "delete" and check the state of pod directly
# time kubectl delete rc test-delete && kubectl get pod
replicationcontroller "test-delete" deleted
real 0m2.028s
user 0m0.014s
sys 0m0.007s
NAME 				READY 	STATUS 		RESTARTS 	AGE
test-delete-g4xyy 	1/1 	Terminating 0 			1m
test-delete-px9z6 	0/1 	Terminating 0 			1m
test-delete-vctnk 	1/1 	Terminating 0 			1m
test-delete-vsikc 	0/1 	Terminating 0 			1m
test-delete-ye07h 	1/1 	Terminating 0 			1m

我们发现,响应时间相当短,效果也是实时的。

从副本控制器删除Pod

通过删除pod来删除或缩小副本控制器是不可能的,因为当删除pod时,副本控制器将脱离其所需的状态,控制器管理器将要求它创建另一个pod。这个概念显示在以下命令中:

//首先检查一下副本控制器和Pod
# kubectl get rc,pod
CONTROLLER      CONTAINER(S)    IMAGE(S) SELECTOR     REPLICAS AGE
test-delete-pod test-delete-pod nginx    run=testdelete-pod 3 12s
NAME READY STATUS RESTARTS AGE
test-delete-pod-8hooh 1/1 Running 0 14s
test-delete-pod-jwthw 1/1 Running 0 14s
test-delete-pod-oxngk 1/1 Running 0 14s
//删除掉Pod再检查一下pod状态,看看发生了什么
# kubectl delete pod test-delete-pod-8hooh && kubectl get pod
NAME READY STATUS RESTARTS AGE
test-delete-pod-8hooh 0/1 Terminating 0 1m
test-delete-pod-8nryo 0/1 Running 0 3s
test-delete-pod-jwthw 1/1 Running 0 1m
test-delete-pod-oxngk 1/1 Running 0 1m

 

它是如何工作的...

副本控制器根据一个Pod模板和标签来定义一组Pod。正如你从前面之节所了解的,副本控制器仅仅是这它们的标签来管理Pod的。Pod的配置与模板可以不相同。它也意味着独立的Pod也可以通过修改标签将其添加到一个控制器组中。根据以下命令和运行结果,让我们评估一下关于selector和label这两个概念:

// Two pod existed in system already, they have the same label app=nginx
# kubectl get pod -L app -L owner
NAME     READY STATUS  RESTARTS AGE APP   OWNER
web-app1 1/1   Running 0        6m  nginx Amy
web-app2 1/1   Running 0        6m  nginx Bob

然后,我们使用app=nginx选择器标签创建一个具有三个Pod的副本控制器。

# kubectl run rc-wo-create-all --replicas=3 --image=nginx --labels="app=nginx"
replicationcontroller "rc-wo-create-all" created

我们可以查看副本控制器工作工具有三个Pod的期望状态,却只需要启动一个Pod即可。Pod web-app1和web-app2都是由正在运行rc-wo-create-all进行管制:

# kubectl get pod -L app -L owner
NAME READY STATUS RESTARTS AGE APP OWNER
rc-wo-create-all-jojve 1/1 Running 0 5s nginx <none>
web-app1 1/1 Running 0 7m nginx Amy
web-app2 1/1 Running 0 7m nginx Bob

# kubectl describe rc rc-wo-create-all
Name: rc-wo-create-all
Namespace: default
Image(s): nginx
Selector: app=nginx
Labels: app=nginx
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
No volumes.
Events:
FirstSeen LastSeen Count From SubobjectPath Reason
Message
───────── ──────── ───── ──── ───────────── ──────
───────
1m 1m 1 {replication-controller } SuccessfulCreate Created
pod: rc-wo-create-all-jojve

还可以参考

在本章,有几节可以获得关于副本控制器更多的概念:

  • Pod的使用

  • 服务(Services)的使用

  • 标签( Labels)和选择器(Selectors)的使用

  • 第3章玩转容器,操作配置文件