3.Kubernetes权威指南 --- 深入掌握Pod

本文详细探讨了Kubernetes中Pod的概念,作为最基础的部署单元,Pod如何承载应用实例,其生命周期管理,以及Pod在集群中的网络通信机制。通过学习,读者将能够深入掌握Pod在容器化环境中的核心作用。
摘要由CSDN通过智能技术生成
第3章 深入掌握Pod 
3.1 Pod定义详解 

3.2 Pod的基本用法 
	在使用docker时,可以使用docker run命令创建并启动一个容器。而在k8s系统中对长时间运行容器的要求是:其主程序需要一直在前台执行。
如果我们创建docker镜像的启动命令是后台执行程序,例如Linux脚本:
	nohup ./start.sh &

	则在kubelet创建包含这个容器的Pod之后运行完该命令,即认为Pod执行结束,将立即销毁该pod。如果为该pod定义了ReplicationController,
则系统会监控到该pod已经终止,之后根据RC定义中Pod的replicas副本数量生成一个新的pod。一旦创建新的pod,又陷入循环中了。这就是k8s需要我们
自己创建的docker镜像并以一个前台作为启动命令的原因。
	
	对于无法改造成前台执行的应用,可以用Supervisor辅助进行管理。

3.3 静态Pod 
		静态Pod是由kubelet进行管理的仅存在于Node上的Pod。它们不能通过API Server进行管理,无法与ReplicationController、
	Deployment或者DaemonSet进行关联,并且kubelet无法对它们进行健康检查。静态Pod总是由kubelet创建的,并且总在kubelet所在的node
	上运行。

		创建静态pod有2种方式:配置文件方式和HTTP方式。

		1.配置文件方式
			设置kubelet的启动参数 "--pod-manifest-path"。或者在 kubelet 配置文件中设置 staticPodPath,推荐这个。

		2.HTTP方式
			通过设置 kubelet 的启动参数 "--manifest-url",kubelet将会定期从该url地址下载Pod的定义文件,并以.yaml或
		.json文件的格式进行解析,然后创建Pod。其实现方式和配置文件方式是一致的。

3.4 Pod容器共享Volume 
		同一个pod的多个容器能够共享pod级别的存储卷Volume。

3.5 Pod的配置管理 
	3.5.1 ConfigMap概述 
		ConfigMap供容器使用的典型用法如下:
			1.生成为容器内的环境变量
			2.设置容器启动命令的启动参数(需要设置为环境变量)
			3.以Volume的形式挂载为容器内部的文件或目录

		可以通过yaml配置文件或者直接使用 kubectl create configmap 命令行的方式来创建ConfigMap。

	3.5.2 创建ConfigMap资源对象 
		1.通过yaml配置文件方式创建
		//创建ConfigMap
		kubectl create -f cm-appvars.yaml

		//查看创建好的ConfigMap
		kubectl get configmap

		2.通过 kubectl 命令行方式创建
			可以使用 --from-file 或者 --from-literal 指定内容,并且可以在一行命令中指定多个参数。

			a)通过 --from-file 参数从文件中进行创建,可以指定key的名称,也可以在一个命令行中创建包含多个key的ConfigMap
			kubectl create configmap NAME --from-file=[key=]source --from-file=[key=]source

			kubectl create configmap cm-server.xml --from-file=server.xml

			b)通过 --from-file 参数从目录中进行创建,该目录下的每个配置文件名都被设置为key,文件的内容被设置为value,语法为:
			kubectl create configmap NAME --from-file=config-files-dir

			kubectl create configmap cm-appconf --from-file=configfiles

			c)使用 --from-literal 时会从文本中进行创建,直接将指定的 key#=value# 创建为ConfigMap 的内容,语法为:
			kubectl create configmap NAME --from-literal=key1=value1 --from-literal=key2=value2

			kubectl create configmap NAME --from-literal=loglevel=info --from-literal=appdatadir=/var/data


			容器应用对 ConfigMap 的使用有以下2种方式:
				1.通过环境变量获取ConfigMap中的内容
				2.通过Volume挂载的方式将ConfigMap中的内容挂载为容器内部的文件或目录

	3.5.3 在Pod中使用ConfigMap 
		1.通过环境变量方式使用ConfigMap

		2.通过 volumeMount 使用 ConfigMap

	3.5.4 使用ConfigMap的限制条件 
		1.ConfigMap 必须在pod之前创建
		2.ConfigMap 受 Namespace 限制,只有处于相同 namespace 中的pod菜可以引用它
		3.ConfigMap中的配额管理还未能实现
		4.kubelet只支持可以被 api server 管理的Pod使用ConfigMap。kubelet在Node上通过 --manifest-url 或者 --config自动
		创建的静态pod将无法引用ConfigMap
		5.在pod对ConfigMap进行挂载操作时,在容器内部只能挂载为目录,无法挂载为文件。在挂载到容器内部后,在目录下将包含ConfigMap
		定义的每个item,如果在该目录下原来还有其他文件,则容器内的该目录将被挂载的ConfigMap覆盖。如果应用程序需要保留原来的其他文件,
		则需要进行额外的处理。可以将ConfigMap挂载到容器内部的临时目录,再通过启动脚本将配置文件复制或者链接到(cp或者link)应用所用
		的实际配置目录下

3.6 在容器内获取Pod信息(Downward API)
		每个pod被创建出来之后,都会被系统分配唯一的名字、IP地址,并且处于某个namespace中,那么如何在pod的容器如何获取这些信息呢?
	答案是Downward API。

		Downward API 可以通过下面2种方式将pod的信息注入容器内部:
			1.环境变量:用于单个变量,可以将pod信息和Container信息注入容器内部
			2.Volume挂载:将数组类信息生成文件并挂载到容器内部
	
	3.6.1 环境变量方式:将Pod信息注入为环境变量 
	3.6.2 环境变量方式:将容器资源信息注入为环境变量 
	3.6.3 Volume挂载方式 

3.7 Pod生命周期和重启策略 
	Pod的状态:
		1.Pending
			API Server已经创建该pod,但在pod内还有一个或者多个容器的镜像没有创建,包括正在下载镜像的过程。
		2.Running
			pod内所有容器均创建,且至少有一个容器处于运行状态、正在启动或者重启状态。
		3.Succeeded
			pod内所有容器均成功执行后退出,且不会再重启。
		4.Failed
			pod内所有容器均已退出,但至少有一个容器退出为失败状态。
		5.Unknown
			由于某种原因无法获取该pod的状态,可能由于网络通信不畅导致的。

	Pod的重启策略(RestartPolicy),pod的重启策略应用于pod内的所有容器,并且仅在pod所处的Node上由kubectl进行判断和重启操作。当某个
容器异常退出或者健康检查失败时,kubelet 将根据 RestartPolicy 的设置来进行相应的操作:
	1.Always
		当容器失败时,由kubelet自动重启该容器;
	2.OnFailure
		当容器终止运行时且退出码不为0时,由kubelet自动重启该容器;
	3.Never
		不论容器运行状态如何,kubelet都不会重启该容器。

3.8 Pod健康检查和服务可用性检查 
	 k8s 对pod的健康状态可以通过两类探针来检查:LivenessProbe和ReadinessProbe,kubelet定期执行者两类探针来诊断容器的健康情况。

	 1.LivenessProbe探针
	 	用于判断容器是否存活(Running状态),如果LivenessProbe探针探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做
	 相应的处理。如果一个容器不包含Linveness探针,那么kubelet认为该容器的LivenessProbe探针返回的值永远是Success。

	 2.ReadinessProbe探针
	 	用于判断容器服务是否可用(Ready状态),达到Ready状态的Pod菜可以接收请求。对于被Service管理的pod,Service与Pod Endpoint
	 的关联关系也将基于pod是否Ready进行设置。如果在运行过程中Ready状态变成False,则系统自动将其从Service的后端Endpoint列表中
	 隔离出去,后续再把恢复到Ready状态的Pod加回后端Endpoint列表。这样就能保证客户端在访问Service时不会被转发到服务不可用的pod实例
	 上。

	 LivenessProbe和ReadinessProbe均可配置以下三种实现方式:
	 	1.ExecAction
	 		在容器内部执行一个命令,如果该命令返回0,则表明容器是健康的。
	 	2.TCPSocketAction
	 		通过容器的ip地址和端口进行tcp检查,如果能够建立tcp连接,则表明容器健康。
	 	3.HTTPGetAction
	 		通过容器的ip地址、端口号以及路径调用HTTP Get方法,如果响应的状态码大于200且小于400,则认为容器是健康的。

3.9 玩转Pod调度 
		在k8s平台上,我们很少会直接创建一个pod,大多数情况下都是通过RC、Deployment、DaemonSet、Job等控制器完成对一组Pod副本的
	创建、调度以及生命周期的自动控制任务。

		我们不应该直接使用底层的ReplicaSet控制Pod副本,而应该使用管理ReplicaSet的Deployment对象来控制副本,官方建议。

	3.9.1 Deployment或RC:全自动调度 
		Deployment或者RC的主要功能之一就是自动部署一个容器应用的多份副本,以及持续监控副本的数量,在集群内始终维持用户指定的副本数量。

	3.9.2 NodeSelector:定向调度 
		有时候需要将一些pod调度到指定的一些Node上。

		1.首选in通过 kubectl label 命令给目标 Node 上打一些标签
		kubectl label nodes <node-name> <label-key>=<label-value>

		//打上 zone=north 的标签,也可以通过修改资源定义文件的方式,并执行 kubectl replace -f xxx.yaml 的方式
		kubectl label nodes node1 zone=north

		2.然后,在pod的定义中加上 nodeSelector的设置

		3.kubectl create -f xxx.yaml ,创建该pod

		4.kubectl get pods -o wide,查看

		如果我们指定了pod的 nodeSelector 条件,且在集群中不存在包含相应标签的node,则即时在集群中还有其他可供使用的node,这个
	pod也无法被成功调度。

		NodeSelector 通过标签的方式,简单的实现了限制pod所在节点的方法。亲和性调度机制则极大扩展了pod的调度能力,主要的增强功能
	如下:
		1.根据表达力
		2.可以使用软限制、优先采用等限制方式,代替之前的硬限制,这样调度器在无法满足优先需求的情况下,会退而求其次,继续运行该pod
		3.可以依据节点上正在运行的其他pod的标签来进行限制,而非节点本身的标签。这样就可以定义一种规则来描述pod之间的亲和或互斥关系


	3.9.3 NodeAffinity:Node亲和性调度 
		目前有两种亲和性表达:
			1.RequiredDuringSchedulingIgnoredDuringExecution
				必须满足指定的规则才可以调度pod到node上,与 nodeSelector很像,但是使用不同的语法。相当于硬限制。
			2.PreferredDuringSchedulingIgnoredDuringExecution
				强调优先满足指定规则,调度器会尝试调度pod到node上,但不强求,相当于软限制。多个优先级规则还可以设置权重值,以定义
			执行的先后顺序。

		IgnoredDuringExecution的意思是:如果一个pod所在的节点在pod运行期间标签发生了变更,不再符合该pod节点亲和性需求,则系统
	将忽略node上label的变化,该Pod能继续在该节点上运行。


	3.9.4 PodAffinity:Pod亲和与互斥调度策略 
		这一功能让用户从另一个角度来限制pod所能运行的节点:根据节点上正在运行的pod标签而不是节点的标签进行判断和调度,要求对节点和pod
	2个条件进行匹配。

	3.9.5 Taints和Tolerations(污点和容忍) 
		前面介绍的NodeAffinity节点亲和性,是在pod上定义的一种属性,使得pod能够被调度到某些Node上运行(优先或者强制要求)。Taint则
	正好相反,它让Node拒绝pod的运行。

		Taint 需要和 Toleration 配合使用,让pod避开那些不合适的node。在node上设置一个或者多个 Taint之后,除非Pod明确声明能够
	容忍这些污点,否则无法再这些node上运行。Toleration是pod的属性,让pod能够(注意只是能够,而非必须)运行在标注了Taint的node上。

		1.可以用 kubectl taint 命令为 node 设置 Taint 信息
		kubectl taint nodes node1 key=value:NoSchedule

		这个设置为node1加上了一个Taint,该 Taint 的键为key,值为value,Taint的效果是 NoSchedule。这意味着除非pod明确声明可以
	容忍这个Taint,否则就不会被调度到 node1上。

		然后,需要在pod上声明 Toleration。下面的2个 Toleration 都被设置为可以容忍(Toleration)具有该Taint的node,使得pod
	能够被调度到node1上。
tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"
--------
tolerations:
- key: "key"
  operator: "Exists"
  effect: "NoSchedule"

  		pod 的 Toleration 声明中的key和effect需要与Taint的设置保持一致,并且满足下面条件之一:
  			1.operator的值是 Exists(无需指定value)
  			2.operator的值是 Equal并且value相等

  		如果不指定 operator,则默认值为 Equal。

  		另外,还有如下两个特例:
  			1.空的key配合Exists操作符能够匹配所有的键和值
  			2.空的effect匹配所有的effect


  		系统允许在同一个node上设置多个 Taint,也可以在pod上设置多个Toleration。k8s调度器处理多个 Taint和Toleration的逻辑
  	顺序为:首先列出节点中所有的 Taint,然后忽略pod的 Toleration能够匹配的部分,剩下的没有忽略的Taint就是对pod的效果了。下面是
  	几种特殊情况:
  		1.如果在剩余的Taint中存在 effect=NoSchedule,则调度器不会把该pod调度到这一节点上;
  		2.如果在剩余的 Taint 中没有 NoSchedule 效果,但是有 PreferNoSchedule效果,则调度器会尝试不把这个pod指派给这个节点;
  		3.如果在剩余的Taint中有 NoExecute效果,并且这个pod已经在该节点上运行,则会被驱逐;如果没有在该节点上运行,则也不会在被调度
  		到该节点上。


  	常见应用:	
  		1.独占节点
  			kubectl taint nodes nodename dedicated=groupName:NoSchedule

  			然后给这些应用的pod加入对应的Toleration,这样,带有合适 Toleration 的Pod就会被允许同使用其他节点一样使用有Taint的节点

  		2.具有特殊硬件设备的节点
  			kubectl taint nodes nodename special=true:NoSchedule
  			kubectl taint nodes nodename special=true:PreferNoSchedule

  		3.定义Pod的驱逐行为,以应对节点故障
  			前面提到的 NoExecute 这个 Taint 效果对节点上正在运行的Pod有以下影响:
  				1.没有设置 Toleration 的pod 会被立即驱逐
  				2.配置了对应的 Toleration的pod,如果没有为 tolerationSeconds 赋值,则会一直留在这一节点中
  				3.配置了对应的 Toleration的pod且指定了 tolerationSeconds 值,则会在指定时间后驱逐
  				4.k8s从1.6版本开始引入一个Alpha版本的功能,即把节点故障标记为 Taint


	3.9.6 Pod Priority Preemption:Pod优先级调度 
		抢占式调度几个维度:
			1.Priority,优先级
			2.QoS,服务质量等级
			3.系统定义的其他度量指标

		优先级抢占调度策略的核心行为分别是 驱逐(Eviction)和抢占(Preemption),这2种行为的使用场景不同,效果相同。Eviction是
	kubelet进程的行为,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值