您的位置:首页 > 其它

Kubernetes之深入了解Pod

2017-07-17 11:05 585 查看
时间:2017-04-14 13:22:14
 
1、yaml格式的Pod配置文件内容及注解
  深入Pod之前,首先我们来了解下Pod的yaml整体文件内容及功能注解。
如下:

# yaml格式的pod定义文件完整内容:
apiVersion: v1        #必选,版本号,例如v1
kind: Pod       #必选,Pod
metadata:       #必选,元数据
name: string        #必选,Pod名称
namespace: string     #必选,Pod所属的命名空间
labels:       #自定义标签
- name: string      #自定义标签名字
annotations:        #自定义注释列表
- name: string
spec:         #必选,Pod中容器的详细定义
containers:       #必选,Pod中容器列表
- name: string      #必选,容器名称
image: string     #必选,容器的镜像名称
imagePullPolicy: [Always | Never | IfNotPresent]  #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
command: [string]     #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string]      #容器的启动命令参数列表
workingDir: string      #容器的工作目录
volumeMounts:     #挂载到容器内部的存储卷配置
- name: string      #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string     #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean     #是否为只读模式
ports:        #需要暴露的端口库号列表
- name: string      #端口号名称
containerPort: int    #容器需要监听的端口号
hostPort: int     #容器所在主机需要监听的端口号,默认与Container相同
protocol: string      #端口协议,支持TCP和UDP,默认TCP
env:        #容器运行前需设置的环境变量列表
- name: string      #环境变量名称
value: string     #环境变量的值
resources:        #资源限制和请求的设置
limits:       #资源限制的设置
cpu: string     #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string      #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests:       #资源请求的设置
cpu: string     #Cpu请求,容器启动的初始可用数量
memory: string      #内存清楚,容器启动的初始可用数量
livenessProbe:      #对Pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
exec:       #对Pod容器内检查方式设置为exec方式
command: [string]   #exec方式需要制定的命令或脚本
httpGet:        #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket:      #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0   #容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0    #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0     #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure] #Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
nodeSelector: obeject   #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
imagePullSecrets:     #Pull镜像时使用的secret名称,以key:secretkey格式指定
- name: string
hostNetwork: false      #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes:        #在该pod上定义共享存储卷列表
- name: string      #共享存储卷名称 (volumes类型有很多种)
emptyDir: {}      #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string      #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string      #Pod所在宿主机的目录,将被用于同期中mount的目录
secret:       #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
scretname: string
items:
- key: string
path: string
configMap:      #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string


 

2、Pod基本用法:
  在使用docker时,我们可以使用docker run命令创建并启动一个容器,而在Kubernetes系统中对长时间运行的容器要求是:其主程序需要一直在前台运行。如果我们创建的docker镜像的启动命令是后台执行程序,例如Linux脚本:
  nohup ./startup.sh &
  则kubelet创建包含这个容器的pod后运行完该命令,即认为Pod执行结束,之后根据RC中定义的pod的replicas副本数量生产一个新的pod,而一旦创建出新的pod,将在执行完命令后陷入无限循环的过程中,这就是Kubernetes需要我们创建的docker镜像以一个前台命令作为启动命令的原因。
  对于无法改造为前台执行的应用,也可以使用开源工具supervisor辅助进行前台运行的功能。
****Pod可以由一个或多个容器组合而成
例如:两个容器应用的前端frontend和redis为紧耦合的关系,应该组合成一个整体对外提供服务,则应该将这两个打包为一个pod.
配置文件frontend-localredis-pod.yaml如下:

apiVersion:v1
kind: Pod
metadata:
name: redis-php
label:
name: redis-php
spec:
containers:
- name: frontend
image: kubeguide/guestbook-php-frontend:localredis
ports:
- containersPort: 80
- name: redis-php
image:kubeguide/redis-master
ports:
- containersPort: 6379


  

  属于一个Pod的多个容器应用之间相互访问只需要通过localhost就可以通信,似的这一组容器被绑定在一个环境中。
  使用kubectl create创建该Pod后,get Pod信息可以看到如下图:

#kubectl get gods
NAME READY STATUS RESTATS AGE
redis-php 2/2 Running 0 10m


  可以看到READY信息为2/2,表示Pod中的两个容器都成功运行了.

  查看pod的详细信息,可以看到两个容器的定义和创建过程。

[root@kubernetes-master ~]# kubectl describe redis-php
the server doesn‘t have a resource type "redis-php"
[root@kubernetes-master ~]# kubectl describe pod redis-php
Name: redis-php
Namespace: default
Node: kubernetes-minion/10.0.0.23
Start Time: Wed, 12 Apr 2017 09:14:58 +0800
Labels: name=redis-php
Status: Running
IP: 10.1.24.2
Controllers: <none>
Containers:
nginx:
Container ID: docker://d05b743c200dff7cf3b60b7373a45666be2ebb48b7b8b31ce0ece9be4546ce77
Image: nginx
Image ID: docker-pullable://docker.io/nginx@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582
Port: 80/TCP
State: Running
Started: Wed, 12 Apr 2017 09:19:31 +0800


  

3、静态Pod
  静态pod是由kubelet进行管理的仅存在于特定Node的Pod上,他们不能通过API Server进行管理,无法与ReplicationController、Deployment或者DaemonSet进行关联,并且kubelet无法对他们进行健康检查。静态Pod总是由kubelet进行创建,并且总是在kubelet所在的Node上运行。
创建静态Pod有两种方式:配置文件或者HTTP方式
1)配置文件方式
  首先,需要设置kubelet的启动参数"--config",指定kubelet需要监控的配置文件所在的目录,kubelet会定期扫描该目录,冰根据目录中的 .yaml或 .json文件进行创建操作
假设配置目录为/etc/kubelet.d/配置启动参数:--config=/etc/kubelet.d/,然后重启kubelet服务后,再宿主机受用docker ps或者在Kubernetes Master上都可以看到指定的容器在列表中
由于静态pod无法通过API Server直接管理,所以在master节点尝试删除该pod,会将其变为pending状态,也不会被删除

#kubetctl delete pod static-web-node1
pod "static-web-node1" deleted
#kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web-node1 0/1 Pending 0 1s


  

  要删除该pod的操作只能在其所在的Node上操作,将其定义的.yaml文件从/etc/kubelet.d/目录下删除

#rm -f /etc/kubelet.d/static-web.yaml
#docker ps


  

4、Pod容器共享Volume
  Volume类型包括:emtyDir、hostPath、gcePersistentDisk、awsElasticBlockStore、gitRepo、secret、nfs、scsi、glusterfs、persistentVolumeClaim、rbd、flexVolume、cinder、cephfs、flocker、downwardAPI、fc、azureFile、configMap、vsphereVolume等等,可以定义多个Volume,每个Volume的name保持唯一。在同一个pod中的多个容器能够共享pod级别的存储卷Volume。Volume可以定义为各种类型,多个容器各自进行挂载操作,讲一个Volume挂载为容器内需要的目录。
如下图:


 

  如上图中的Pod中包含两个容器:tomcat和busybox,在pod级别设置Volume “app-logs”,用于tomcat想其中写日志文件,busybox读日志文件。
配置文件如下:

apiVersion:v1
kind: Pod
metadata:
name: redis-php
label:
name: volume-pod
spec:
containers:
- name: tomcat
image: tomcat
ports:
- containersPort: 8080
volumeMounts:
- name: app-logs
mountPath: /usr/local/tomcat/logs
- name: busybox
image:busybox
command: ["sh","-C","tail -f /logs/catalina*.log"]
volumes:
- name: app-logs
emptyDir:{}


busybox容器可以通过kubectl logs查看输出内容

#kubectl logs volume-pod -c busybox 


tomcat容器生成的日志文件可以登录容器查看

#kubectl exec -ti volume-pod -c tomcat -- ls /usr/local/tomcat/logs


5.Pod的配置管理
 
 .......
6.Pod生命周期和重启策略
  Pod在整个生命周期过程中被定义为各种状态,熟悉Pod的各种状态有助于理解如何设置Pod的调度策略、重启策略
  Pod的状态包含以下几种,如图:


  
  Pod的重启策略(RestartPolicy)应用于Pod内所有的容器,并且仅在Pod所处的Node上由kubelet进行判断和重启操作。当某哥容器异常退出或者健康检查石柏师,kubelet将根据RestartPolicy的设置进行相应的操作
  Pod的重启策略包括Always、OnFailure及Nerver,默认值为Always。
  kubelet重启失效容器的时间间隔以sync-frequency乘以2n来计算,例如1、2、4、8倍等,最长延时5分钟,并且成功重启后的10分钟后重置该事件。
  Pod的重启策略和控制方式息息相关,当前可用于管理Pod的控制器宝库ReplicationController、Job、DaemonSet及直接通过kubelet管理(静态Pod),每种控制器对Pod的重启策略要求如下:

RC和DaemonSet:必须设置为Always,需要保证该容器持续运行
Job:OnFailure或Nerver,确保容器执行完成后不再重启
kubelet:在Pod失效时重启他,不论RestartPolicy设置什么值,并且也不会对Pod进行健康检查

 
7、Pod健康检查
  对Pod的健康检查可以通过两类探针来检查:LivenessProbe和ReadinessProbe

LivenessProbe探针:用于判断容器是否存活(running状态),如果LivenessProbe探针探测到容器不健康,则kubelet杀掉该容器,并根据容器的重启策略做响应处理
ReadinessProbe探针:用于判断容器是否启动完成(ready状态),可以接受请求。如果ReadinessProbe探针探测失败,则Pod的状态被修改。Endpoint Controller将从service的Endpoint中删除包含该容器所在的Pod的Endpoint。

  kubelet定制执行LivenessProbe探针来诊断容器的健康状况。LivenessProbe有三种事项方式。
 
(1)ExecAction:在容器内部执行一个命令,如果该命令的返回值为0,则表示容器健康
例:

apiVersion:v1
kind: Pod
metadata:
name: liveness-exec
label:
name: liveness
spec:
containers:
- name: tomcat
image: grc.io/google_containers/tomcat
args:
- /bin/sh
- -c
- echo ok >/tmp.health;sleep 10; rm -fr /tmp/health;sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/health
initianDelaySeconds:15
timeoutSeconds:1 


(2)TCPSocketAction:通过容器ip地址和端口号执行TCP检查,如果能够建立tcp连接表明容器健康
例:

kind: Pod
metadata:
name: pod-with-healthcheck
spec:
containers:
- name: nginx
image: nginx
livenessProbe:
tcpSocket:
port: 80
initianDelaySeconds:30
timeoutSeconds:1


(3)HTTPGetAction:通过容器Ip地址、端口号及路径调用http get方法,如果响应的状态吗大于200且小于400,则认为容器健康
例:

apiVersion:v1
kind: Pod
metadata:
name: pod-with-healthcheck
spec:
containers:
- name: nginx
image: nginx
livenessProbe:
httpGet:
path: /_status/healthz
port: 80
initianDelaySeconds:30
timeoutSeconds:1


  

对于每种探针方式,都需要设置initialDelaySeconds和timeoutSeconds两个参数,它们含义如下:
initialDelaySeconds:启动容器后首次监控检查的等待时间,单位秒
timeouSeconds:健康检查发送请求后等待响应的超时时间,单位秒。当发生超时就被认为容器无法提供服务无,该容器将被重启
 
8.玩转Pod调度
  在Kubernetes系统中,Pod在大部分场景下都只是容器的载体而已,通常需要通过RC、Deployment、DaemonSet、Job等对象来完成Pod的调度和自动控制功能。
8.1 RC、Deployment:全自动调度
  RC的主要功能之一就是自动部署容器应用的多份副本,以及持续监控副本的数量,在集群内始终维护用户指定的副本数量。
在调度策略上,除了使用系统内置的调度算法选择合适的Node进行调度,也可以在Pod的定义中使用NodeSelector或NodeAffinity来指定满足条件的Node进行调度。
1)NodeSelector:定向调度
  Kubernetes Master上的scheduler服务(kube-Scheduler进程)负责实现Pod的调度,整个过程通过一系列复杂的算法,最终为每个Pod计算出一个最佳的目标节点,通常我们无法知道Pod最终会被调度到哪个节点上。实际情况中,我们需要将Pod调度到我们指定的节点上,可以通过Node的标签和pod的nodeSelector属性相匹配来达到目的。
(1)首先通过kubectl label命令给目标Node打上标签
kubectl label nodes <node-name> <label-key>=<label-value>
例:

#kubectllabel nodes k8s-node-1 zonenorth


(2)然后在Pod定义中加上nodeSelector的设置
例:

apiVersion:v1
kind: Pod
metadata:
name: redis-master
label:
name: redis-master
spec:
replicas: 1
selector:
name: redis-master
template:
metadata:
labels:
name: redis-master
spec:
containers:
- name: redis-master
images: kubeguide/redis-master
ports:
- containerPort: 6379
nodeSelector:
zone: north 


运行kubectl create -f命令创建Pod,scheduler就会将该Pod调度到拥有zone=north标签的Node上。 如果多个Node拥有该标签,则会根据调度算法在该组Node上选一个可用的进行Pod调度。
需要注意的是:如果集群中没有拥有该标签的Node,则这个Pod也无法被成功调度。
 
2)NodeAffinity:亲和性调度
该调度策略是将来替换NodeSelector的新一代调度策略。由于NodeSelector通过Node的Label进行精确匹配,所有NodeAffinity增加了In、NotIn、Exists、DoesNotexist、Gt、Lt等操作符来选择Node。调度侧露更加灵活。
 
8.2 DaemonSet:特定场景调度
DaemonSet用于管理集群中每个Node上仅运行一份Pod的副本实例,如图


 

这种用法适合一些有下列需求的应用:
在每个Node上运行个以GlusterFS存储或者ceph存储的daemon进程
在每个Node上运行一个日志采集程序,例如fluentd或者logstach
在每个Node上运行一个健康程序,采集Node的性能数据。
DaemonSet的Pod调度策略类似于RC,除了使用系统内置的算法在每台Node上进行调度,也可以在Pod的定义中使用NodeSelector或NodeAffinity来指定满足条件的Node范围来进行调度。
 
8.3 批处理调度
 
9.Pod的扩容和缩荣
  在实际生产环境中,我们经常遇到某个服务需要扩容的场景,也有可能因为资源精确需要缩减资源而需要减少服务实例数量,此时我们可以Kubernetes中RC提供scale机制来完成这些工作。
以redis-slave RC为例,已定义的最初副本数量为2,通过kubectl scale命令可以将Pod副本数量重新调整

#kubectl scale rc redis-slave --replicas=3
ReplicationController "redis-slave" scaled
#kubectl get pods
NAME READY STATUS RESTARTS AGE
redis-slave-1sf23 1/1 Running 0 1h
redis-slave-54wfk 1/1 Running 0 1h
redis-slave-3da5y 1/1 Running 0 1h 


  除了可以手工通过kubectl scale命令完成Pod的扩容和缩容操作以外,新版本新增加了Horizontal Podautoscaler(HPA)的控制器,用于实现基于CPU使用路进行启动Pod扩容缩容的功能。该控制器基于Mastger的kube-controller-manager服务启动参数 --horizontal-pod-autoscler-sync-period定义的时长(默认30秒),周期性监控目标Pod的Cpu使用率并在满足条件时对ReplicationController或Deployment中的Pod副本数量进行调整,以符合用户定义的平均Pod
Cpu使用率,Pod Cpu使用率来源于heapster组件,所以需预先安装好heapster。
 
 
 持续更新中。。。。。。。。。。。。。。。。

原文:http://www.cnblogs.com/xhyan/p/6708344.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: