Just Do IT !

Kubernetes(K8s)入门到实践(六)----深入掌握Pod

字数统计: 3k阅读时长: 11 min
2020/04/21 Share

上几章写了Kubernetes的基本概念与集群搭建
接下来将深入探索Pod的应用、配置、调度、升级及扩缩容,讲述Kubernetes容器编排。

本章将对Kubernetes如何发布与管理容器应用进行详细说明和示例,主要包括Pod和容器的使用、应用配置管理、Pod的控制和调度管理、Pod的升级和回滚,以及Pod的扩缩容机制等内容

深入掌握Pod

Pod定义

Pod定义文件的yaml格式完整版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
apiVersion: v1                    #必选,版本号,例如v1,版本号必须可以用 kubectl api-versions 查询到 .
kind: Pod        #必选,Pod
metadata:        #必选,元数据
name: string    #必选,Pod名称
namespace: string    #必选,Pod所属的命名空间,默认为"default"
labels:        #自定义标签
- name: string   #自定义标签名字
annotations:    #自定义注释列表
- name: string
spec:         #必选,Pod中容器的详细定义
containers:      #必选,Pod中容器列表
- name: string    #必选,容器名称,需符合RFC 1035规范
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

静态Pod

静态Pod是由kubelet进行管理的仅存在于特定Node上的Pod。

它们不能通过API Server进行管理,无法与ReplicationController、Deployment或者DaemonSet进行关联,并且kubelet无法对它们进行健康检查。

静态Pod总是由kubelet创建的,并且总在kubelet所在的Node上运行。创建静态Pod有两种方式:

  • 配置文件方式
  • HTTP方式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    apiVersion: v1
    kind: Pod
    metadata:
    name: pod-demo
    namespace: default
    labels:
    app: myapp
    spec:
    containers:
    - name: myapp-1
    image: plutoacharon/myapp:v1
    - name: busybox-1
    image: busybox:latest
    command: - "/bin/sh" - "-c" - "sleep 3600"

Pod容器共享Volume

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

Volume可以被定义为各种类型,多个容器各自进行挂载操作,将一个Volume挂载为容器内部需要的目录
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
name: cache-volume
emptyDir: {}

emptyDir

当 Pod 被分配给节点时,首先创建emptyDir卷,并且只要该 Pod 在该节点上运行,该卷就会存在。

正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。

当出于任何原因从节点中删除 Pod 时,emptyDir中的数据将被永久删除

emptyDir的用法有:

  • 暂存空间,例如用于基于磁盘的合并排序

  • 用作长时间计算崩溃恢复时的检查点

  • Web服务器容器提供数据时,保存内容管理器容器提取的文件

ConfigMap概述

ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。

ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者 JSON 二进制大对象

ConfigMap供容器使用的典型用法如下。

  • 生成为容器内的环境变量。
  • 设置容器启动命令的启动参数(需设置为环境变量)
  • 以Volume的形式挂载为容器内部的文件或目录。

ConfigMap以一个或多个key:value的形式保存在Kubernetes系统中供应用使用,既可以用于表示一个变量的值(例如apploglevel=info),也可以用于表示一个完整配置文件的内容(例如server.xml=<?xml…>…)

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

使用ConfigMap的限制条件使用ConfigMap的限制条件如下。

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

容器内获取Pod信息(DownwardAPI)

我们知道,每个Pod在被成功创建出来之后,都会被系统分配唯一的名字、IP地址,并且处于某个Namespace中,那么我们如何在Pod的容器内获取Pod的这些重要信息呢?答案就是使用Downward API。

Downward API可以通过以下两种方式将Pod信息注入容器内部。

  • 环境变量:用于单个变量,可以将Pod信息和Container信息注入容器内部。
  • Volume挂载:将数组类信息生成为文件并挂载到容器内部。

Pod生命周期和重启策略

挂起(Pending):Pod已被Kubernetes系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间,这可能需要花点时间

运行中(Running):该Pod已经绑定到了一个节点上,Pod中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态成功(Succeeded):Pod中的所有容器都被成功终止,并且不会再重启

失败(Failed):Pod中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止

未知(Unknown):因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败

Pod的重启策略(RestartPolicy)应用于Pod内的所有容器,并且仅在Pod所处的Node上由kubelet进行判断和重启操作。当某个容器异常退出或者健康检查失败时,kubelet将根据RestartPolicy的设置来进行相应的操作。Pod的重启策略包括Always、OnFailure和Never,默认值为Always。

  • Always:当容器失效时,由kubelet自动重启该容器。
  • OnFailure:当容器终止运行且退出码不为0时,由kubelet自动重启该容器。
  • Never:不论容器运行状态如何,kubelet都不会重启该容器。

kubelet重启失效容器的时间间隔以sync-frequency乘以2n来计算,例如1、2、4、8倍等,最长延时5min,并且在成功重启后的10min后重置该时间。

Pod的重启策略与控制方式息息相关,当前可用于管理Pod的控制器包ReplicationController、Job、DaemonSet及直接通过kubelet管理(静态Pod)。每种控制器对Pod的重启策略要求如下

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

Pod健康检查和服务可用性检查

Kubernetes 对 Pod 的健康状态可以通过两类探针来检查:LivenessProbe 和ReadinessProbe,kubelet定期执行这两类探针来诊断容器的健康状况。

  • LivenessProbe探针:用于判断容器是否存活(Running状态),如果LivenessProbe探针探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应的处理。如果一个容器不包含LivenessProbe探针,那么kubelet认为该容器的LivenessProbe探针返回的值永远是Success。
  • ReadinessProbe探针:用于判断容器服务是否可用(Ready状态),达到Ready状态的Pod才可以接收请求。对于被Service管理的Pod,Service与Pod Endpoint的关联关系也将基于Pod是否Ready进行设置。如果在运行过程中Ready状态变为False,则系统自动将其从Service的后端Endpoint列表中隔离出去,后续再把恢复到Ready状态的Pod加回后端Endpoint列表。这样就能保证客户端在访问Service时不会被转发到服务不可用的Pod实例上。
CATALOG
  1. 1. 深入掌握Pod
    1. 1.1. Pod定义
    2. 1.2. 静态Pod
    3. 1.3. Pod容器共享Volume
      1. 1.3.1. emptyDir
    4. 1.4. ConfigMap概述
    5. 1.5. 容器内获取Pod信息(DownwardAPI)
    6. 1.6. Pod生命周期和重启策略
    7. 1.7. Pod健康检查和服务可用性检查