上几章写了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
76apiVersion: 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
14apiVersion: 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实例上。