• docker version:19.03.14
  • kubernetes version:1.19.4

** 已了解Kubernetes的组成、安装、以及kubectl基本命令使用

本文概述Kubernetes中workloads资源控制器基本信息以及Pods资源的介绍。

workloads

工作负载(workloads)是在Kubernetes上运行的应用程序。无论负载是单一组件还是有多个一同工作的组件构成,在Kubernetes中均可以在一组Pods中运行它。

在Kubernetes中,Pod代表的是集群上处于运行状态的一组容器。

Pods有确定的生命周期,使用中通常并不需要直接管理每个Pod。可以使用负载资源来管理一组Pods。这些资源配置控制器(controllers)来确保合适类型的、处于运行状态的Pod个数是正确的且与指定状态是相一致的。

资源控制器

Kubernetes常用资源、对象:

  • Pods
  • workloads资源
  • 服务发现及均衡
  • 配置与存储
  • 集群级资源
  • 元数据型资源

基础介绍

workload主要包含以下资源:

  1. Deployment和ReplicaSet(替换ReplicationController)。Deployment很适合用来管理集群上的无状态应用。
  2. StatefulSet。运行有状态应用控制器。
  3. DaemonSet。定义提供节点本地支撑设施的Pods。
  4. Job和Cronjob。定义一些一直运行到结束并停止的任务。Job为一次性任务,Cronjob为重复性任务。

服务发现及均衡资源:

  1. Service
  2. Ingress

存储与配置资源:

  1. Volume
  2. CSI(容器存储接口)
  3. ConfigMap、Secret
  4. DownwardAPI

集群级资源:

  1. Namespace
  2. Node
  3. Role,ClusterRole
  4. RoleBinding,ClusterRoleBinding

元数据型资源:

  1. HPA
  2. PodTamplate
  3. LimitRange

Pods

Pods是在kubernetes中最小可部署的计算单元。

Pod是一组(一个或多个)容器。这些容器共享存储、网络、以及容器运行声明。

Pod类似于共享名称空间和文件系统卷的一组Docker容器。

每个Pod都运行给定应用程序的单个实例,希望横向扩展应用程序,则应该使用多个Pod,每个实例使用一个Pod,其被称为副本(Replication)。通常使用一种workload资源控制器来创建和管理一组Pod副本。

通过命令行使用的Pod操作基础

# 创建一个名称为nginx的pod,镜像为nginx:latest,默认存在于default名称空间
kubectl run nginx --image=nginx # 查看;使用-O wide可查看详细信息;pod可简写为po
kubectl get po -o wide # 为其创建一个服务(暴露端口);--type可指为ClusterIP、NodePort,默认ClusterIP;--port即服务端口;--target-port即后端端口,--protocol即协议、默认TCP;--name即为此service指定名称,可选
kubectl expose po webapp --type=ClusterIP --port=30080 --target-port=80 --protocol=TCP --name=websvc # 查看service可以看到刚才expose的服务端口;service可简写为svc;集群内任意主机可以通过ClusterIP:Port进行访问
kubectl get svc # 删除此pod
kubectl delete po

清单文件

通常使用时很少通过命令行进行创建,一般使用清单文件创建。

清单文件格式

通常使用yaml格式

  • 在文件中字典可使用花括号,或换行缩进
  • 在文件中列表数据可使用中括号或中划线
  • 在一个文件中有多个yaml配置段使用三个中划线对其分隔

示例:

---
json:
- rigid
- better for data interchange
yaml:
- slim and flexible
- better for configuration
object:
key: value
array:
- null_value:
- boolean: true
- integer: 1
paragraph: |
Blank lines denote
paragraph breaks
content: |-
Or we
can auto
convert line breaks
to save space

通过清单文件创建Pod

示例:

apiVersion: v1
kind: Pod
metadata:
name: demo-pod
namespace: default
spec:
containers:
- name: webapp
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: web-port
containerPort: 80
restartPolicy: Never

创建此文件保存至demo-pod.yaml文件,通过命令行创建:

# 当第一次创建此资源可以使用create,当已有该名称的资源存在则不能使用create
kubectl create -f demo-pod.yaml # 使用apply则资源不存在则创建,资源已存在则更新资源状态为文件中的配置
kubectl apply -f demo-pod.yaml

大部分清单文件的的字段:

apiVersion:使用Kubernetes的哪个API资源

kind:资源类别

metadata:元数据

spec:期望状态

status:当前状态;该字段由集群维护

以上示例解释:

apiVersion:指定API资源;Pod控制器使用的api为v1

kind:指定资源类别;Pod资源属于Pod类别

metadata.name:指定此Pod的名称

metadata.namespace:指定此Pod所属的名称空间

spec.containers.name:为容器指定名称

spec.containers.image:指定容器的镜像

spec.containers.imagePullPolicy:指定容器的镜像拉取策略;可使用值为Always、Never、IfNotPresent;

如果镜像的tag是latest则默认值是Always,非latest标签则默认为IfNotPresent;指定Always表示已存在镜像且标签且为latest则总是拉取最新的latest,指定为Never表示永不拉取镜像,指定为IfNotPresent表示不存在则拉取镜像

spec.containers.ports:声明容器要公开的端口列表

spec.containers.ports.name:声明容器要公开的端口的名称

spec.containers.ports.name.containerPort:容器要暴露的端口

spec.restartPolicy:重启策略;Always(默认)、OnFailure、Never

explain

列出支持的资源的字段,此命令描述每个支持的API资源的字段。

通过此命令可以查看清单文件定义时可以使用的资源、字段等详细内容。

kubectl explain RESOURCE [options]

# 列出pod资源spec字段下的子字段
kubectl explain pods.spec # 列出secret资源支持的字段
kubectl explain secret # 列出pod资源spec字段中containers下livenessProbe字段支持的字段
kubectl explain pod.spec.containers.livenessProbe

Pod的生命周期

Pod中创建一个容器可能会包含一些初始化容器(辅助容器),初始化容器完成工作后退出,而后主要容器启动,启动容器后可能会需要postStart等操作,结束过程前可能会需要preStop等操作;其生命周期中可能需要持续保持着livenessProbe及readinessProbe操作。

Pod阶段

Pod的status字段是一个PodStatus对象,其中包含一个phase字段。

Pod的阶段(Phase)是Pod在其生命周期中所处位置的简单宏观概述。

取值 描述
Pending Pod 已被Kubernetes系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待Pod被调度的时间和通过网络下载镜像的时间,
Running Pod已经绑定到了某个节点,Pod中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
Succeeded Pod中的所有容器都已成功终止,并且不会再重启。
Failed Pod中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
Unknown 因为某些原因无法取得Pod的状态。这种情况通常是因为与Pod所在主机通信失败。

容器状态

Kubernetes会跟踪Pod中每个容器的状态,就像它跟踪Pod总体上的阶段(Phase)一样。

一旦调度器将Pod分配给某个节点,kubelet就通过容器运行时开始为Pod创建容器。容器的状态有三种:Waiting、Running、Terminated。

检查Pod中容器的状态,可使用kubectl describe pod <pod-name>

容器重启策略

Pod的spec字段中restartPolicy字段控制容器重启策略;其值为Always、OnFailure、Never,默认是Always。restartPolicy适用于Pod中的所有容器。

Pod状况

Pod的PodStatus对象,其中包含一个PodConditions属组。Pod可能通过也可能未通过其中的一些状况测试。

PodScheduled:Pod已经被调度到某节点;

ContainersReady:Pod中所有容器都已就绪;

Initialized:所有的Init容器都已成功启动;

Ready:Pod可以为请求提供服务,并且应该被添加到对应服务的负载均衡池中。

字段名称 描述
type Pod状况的名称
status 表明该状况是否使用,可能的值为True、False、Unknown
lastProbeTime 上次探测Pod状况时的时间戳
lastTransitionTime Pod上次从一种状态转换到另一种状态时的时间戳
reason 机器刻度的驼峰编码(UpperCamelCase)的文字,表述上次状况变换的原因
message 人类可读的消息,给出上次状况转换的详细

Pod的终止

终止Pod的过程:

  1. 发送删除Pod请求,Pod的优雅终止期限默认值30秒。

  2. 更新API服务器中的Pod对象,记录涵盖优雅终止限期在内Pod的最终死期。超出所计算时间则认为Pod已死(dead)。在Pod运行的节点上,kubelet一旦检测到Pod被标记为正在终止(Terminating ),则开始关闭在本节点上此Pod的进程。

    1 如果Pod中的任一容器定义了preStop回调,则开始运行此回调逻辑。如果超出了优雅终止限期,preStop仍在运行,则会给予该Pod一次性的宽限期(2秒)。如果preStop回调需要较长的时间,可以通过更改terminationGracePeriodSeconds属性值使其正常工作。

    2 kubelet发送TERM信号给每个容器中pid为1的进程

  3. 从对应的端点列表、工作负载资源中移除该Pod,ReplicaSets不再将其视为能够提供服务的副本。

  4. 超出终止宽限期限时,kubelet会触发强制关闭过程。容器运行时会向Pod中所有容器内仍在运行的进程发送SIGKILL信号。 kubelet也会清理隐藏的pause容器(如果有)。

  5. kubelet触发强制从API服务器上删除Pod对象的逻辑,并将优雅终止期限设置为0(意味着马上删除)。

  6. API服务器删除Pod的API对象。

强制终止Pod

默认情况下,所有的删除操作都会附有30秒钟的宽限期限。 kubectl delete命令支持--grace-period=<seconds>选项,允许重载默认值,设定自己希望的期限值。

将宽限期限强制设置为0意味着立即从API服务器删除Pod。

必须在设置--grace-period=0的同时额外设置--force参数才能发起强制删除请求。

执行强制删除操作时,API服务器不再等待来自kubelet的、关于Pod已经在原来运行的节点上终止执行的确认消息。API服务器直接删除Pod对象,这样新的与之同名的Pod即可以被创建。在节点侧,被设置为立即终止的Pod仍然会在被强行杀死之前获得一点点的宽限时间。

失效Pod的垃圾收集

对于已失败的Pod而言,对应的API对象仍然会保留在集群的API服务器上,直到用户或者控制器进程显式地将其删除。

控制面组件会在Pod个数超出所配置的阈值(根据kube-controller-manager的 terminated-pod-gc-threshold设置)时删除已终止的Pod(阶段值为Succeeded或Failed)。这一行为会避免随着时间演进不断创建和终止Pod而引起的资源泄露问题。

容器探针

Probe是由kubelet对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的Handler(处理程序)。有三种类型的处理程序:

ExecAction:在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。

TCPSocketAction:对容器的IP地址上的指定端口执行TCP检查。如果端口打开,则诊断被认为是成功的。

HTTPGetAction:对容器的IP地址上指定端口和路径执行HTTP Get请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的。

每次探测都将获得以下三种结果之一:

Success:容器通过了诊断。

Failure:容器未通过诊断。

Unknown:诊断失败,因此不会采取任何行动。

针对运行中的容器,kubelet可以选择是否执行一下三种探针,以及如何针对探测结果作出反应:

livenessProbe:存活状态探测;指示容器是否正在运行。如果探测失败,则kubelet会杀死容器,并且容器将根据其重启策略决定未来。如果不指定存活状态探针,则默认状态为Success

readinessProbe:就绪状态探测;指示容器是否准备好为请求提供服务。如果探测失败,端点控制器将从与Pod匹配的所有服务的端点列表中删除该Pod的IP地址(即未准备就绪不会将其加入到service的后端)。初始延迟之前的就绪状态值默认为Failure。如果容器不提供就绪状态探针,则默认状态为Success

startupProbe:启动状态探测;指示容器中的应用是否已经启动。如果提供了启动探针,则所有其它探针都会被禁用,直到此探针成功为止。如果启动探测失败,kubelet将杀死容器,以其重启策略重启。如果容器没有提供启动探测探针,则默认状态为Success

存活状态探针

如果容器因为进程遇到问题的情况下自行崩溃,则不一定需要存活状态探针。

如果希望的是容器在探测失败时被杀死并重启,这种情况下就应当使用存活状态探针,并且指定容器重启策略。

常用参数

pod.spec.containers.livenessProbe:启用livenessProbe

pod.spec.containers.livenessProbe.exec:使用命令方式探测,见#容器探针#ExecAction内容

pod.spec.containers.livenessProbe.httpGet:使用http get方式探测,见#容器探针#HTTPGetAction内容

pod.spec.containers.livenessProbe.tcpSocket:使用TCP Socket方式探测,见#容器探针#TCPSocketAction内容

pod.spec.containers.livenessProbe.initialDelaySeconds:延迟探测时间

pod.spec.containers.livenessProbe.periodSeconds:探测时间间隔,默认10s

pod.spec.containers.livenessProbe.successThreshold:成功N次则将状态装换为成功,默认1,最小1

pod.spec.containers.livenessProbe.failureThreshold:失败N次则将状态装换为失败,默认1,最小1

pod.spec.containers.livenessProbe.timeoutSeconds:探测超时时间(秒),默认1,最小1

示例:

使用存活探针探测某个文件是否存在,不存在则视为故障,使其重启且生成此文件。

根据清单文件创建此pod,观察其信息(kubectl describe po liveness-exec pod)中的Events,经过一定次数的探测后,其会提示Liveness probe failed,而后重启此Pod中的容器。

apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "touch /tmp/healthy; sleep 60; rm -f /tmp/healthy; sleep 3600"]
livenessProbe:
exec:
command: ["test", "-e", "/tmp/healthy"]
initialDelaySeconds: 3
periodSeconds: 5
restartPolicy: OnFailure

就绪状态探针

就绪状态探针的存在意味着Pod将在启动阶段不接收任何数据,并且只有在就绪状态探针探测成功后才开始接收数据。

假如容器需要在启动时加载大量数据、配置文件或应用初始化等操作,则应当使用就绪状态探针。

常用参数

pod.spec.containers.readinessProbe:启用readinessProbe

其它参数同livenessProbe

示例:

使用就绪状态探针探测Web服务是否准备就绪,就绪后才开始接受请求。

创建此Pod,观察其READY状态(kubelet get po readiness-httpget-pod),在指定的就绪状态检测次数总和判定为成功之前和之后,其状态变化,则是readinessProbe探针状态的变化。

apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
spec:
containers:
- name: readiness-httpget-container
image: nginx
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
port: 80
initialDelaySeconds: 3
periodSeconds: 5
restartPolicy: Never

启动状态探针

对于所包含的容器需要较长时间才能启动就绪的Pod而言,则应当使用启动探针。如果容器启动时间通常超出initialDelaySeconds + failureThreshold × periodSeconds总值,则应该设置一个启动探测。

periodSeconds的默认值是10秒。应该将其failureThreshold设置得足够高,以便容器有充足的时间完成启动,并且避免更改存活态探针所使用的默认值。这一设置有助于减少死锁状况的发生。

常用参数

pod.spec.containers.startupProbe: 启用startupProbe

其它参数同livenessProbe

lifecycle

在Pod的生命周期中,还存在postStart和preStop两个处理函数。

postStart:当一个容器启动后,立即执行postStart事件

preStop:在容器被终结之前,执行preStop事件

postStart

注意:spec.containers.command执行顺序优先于postStart中的exec.command

常用参数

pod.spec.containers.lifecycle.postStart:启用postStart

pod.spec.containers.lifecycle.postStart.exec:使用命令行执行事件

pod.spec.containers.lifecycle.postStart.httGet:使用http get方法执行事件

pod.spec.containers.lifecycle.postStart.tcpSocket:使用TCP Socket方法执行事件

示例:

创建一个postStart事件,在容器启动后做一些操作

创建此Pod,而后访问其/hello.html文件,则证实postStart处理的事件

apiVersion: v1
kind: Pod
metadata:
name: poststart-pod
namespace: default
spec:
containers:
- name: poststart-pod
image: nginx
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
port: 80
path: /hello.html
initialDelaySeconds: 3
periodSeconds: 5
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo HelloWebServer >>/usr/share/nginx/html/hello.html"]
restartPolicy: Never

preStop

pod.spec.containers.lifecycle.preStop:启用preStop

其它同postStart

Kubernetes-4.Pods的更多相关文章

  1. (转帖)开源容器集群管理系统Kubernetes架构及组件介绍

    最近在搞Docker还有她的管理工具,选型Kuberetes后,被她的术语和概念搞得晕头转向...看了一篇文章还不错,放到这里分享出来. 地址:http://www.linuxidc.com/Linu ...

  2. Openstack+Kubernetes+Docker微服务实践之路--RPC

    重点来了,本文全面阐述一下我们的RPC是怎么实现并如何使用的,跟Kubernetes和Openstack怎么结合.  在选型一文中说到我们选定的RPC框架是Apache Thrift,它的用法是在Ma ...

  3. Kubernetes系统架构简介

    1. 前言 Together we will ensure that Kubernetes is a strong and open container management framework fo ...

  4. kubernetes

    项目主页:http://kubernetes.io/ docker仅能在单机上部署容器,而kubernetes可以统一管理各类容器,形成集群.Kubernetes作为Docker生态圈中重要一员,是G ...

  5. Kubernetes系统架构简介--转

    原文地址:http://www.infoq.com/cn/articles/Kubernetes-system-architecture-introduction?utm_campaign=infoq ...

  6. Google Kubernetes设计文档之服务篇-转

    摘要:Kubernetes是Google开源的容器集群管理系统,构建于Docker之上,为容器化的应用提供资源调度.部署运行.服务发现.扩容缩容等功能. Pod是创建.调度和管理的最小部署单位,本文详 ...

  7. 对比剖析Swarm Kubernetes Marathon编排引擎

    Docker Native Orchestration 基本结构 Docker Engine 1.12 集成了原生的编排引擎,用以替换了之前独立的Docker Swarm项目.Docker原生集群(S ...

  8. Kubernetes 之上的架构应用

    规划并运转一个兼顾可扩展性.可移植性和健壮性的运用是一件很有应战的事情,尤其是当体系杂乱度在不断增长时.运用或体系 本身的架构极大的影响着其运转办法.对环境的依靠性,以及与相关组件的耦合强弱.当运用在 ...

  9. 大型网站技术学习-3. 容器Docker与kubernetes

    大型网站技术基石篇-容器Docker与kubernetes   Docker和Kubernetes的关系就如Xen与OpenStack. Docker是一种容器技术,和Hypervisor(KVM/X ...

  10. 资深专家深度剖析Kubernetes API Server第2章(共3章)

    欢迎来到深入学习Kubernetes API Server的系列文章的第二部分.在上一部分中我们对APIserver总体,相关术语及request请求流进行探讨说明.在本部分文章中,我们主要聚焦于探究 ...

随机推荐

  1. struts 返回字符串

    方法一: HttpServletResponse response = ServletActionContext.getResponse(); response.getWriter().print(& ...

  2. 2017-2018 ACM-ICPC Latin American Regional Programming Contest PART (11/13)

    $$2017-2018\ ACM-ICPC\ Latin\ American\ Regional\ Programming\ Contest$$ \(A.Arranging\ tiles\) \(B. ...

  3. 【洛谷 p3373】模板-线段树 2(数据结构--线段树)

    题意:已知一个数列,你需要进行下面三种操作:1.将某区间每一个数加上x:2.将某区间每一个数乘上x:3.求出某区间每一个数的和. 解法:(唉 :-(,这题卡住我了......)对于加法和乘法的混合操作 ...

  4. 一维二维Sparse Table

    写在前面: 记录了个人的学习过程,同时方便复习 Sparse Table 有些情况,需要反复读取某个指定范围内的值而不需要修改 逐个判断区间内的每个值显然太浪费时间 我们希望用空间换取时间 ST表就是 ...

  5. Medium Free

    fetch(window.location.href,{credentials:"omit",redirect:"follow",mode:"no-c ...

  6. [Golang]-7 定时器和打点器

    目录 定时器 打点器 After()方法 我们常常需要在未来某个时刻运行 Go 代码,或者在某段时间间隔内重复运行. Go 的内置 定时器 和 打点器 特性让这些很容易实现. 定时器 type Tim ...

  7. DCL 数据控制语言

    目录 授予权限(GRANT) 回收权限(REVOTE) 授予权限(GRANT) # 语法 mysql> help grant; Name: 'GRANT' Description: Syntax ...

  8. Linux添加系统调用

    Linux添加系统调用 1 概述 通常添加系统调用有两种方案: * 重新编译内核 * 添加内核模块 此处我们采用重新编译内核的方式增加系统调用. 实验环境:X86_64 GNU/Linux 4.15. ...

  9. codeforces 1029E Tree with Small Distances【思维+贪心】 【非原创】

    题目:戳这里 学习博客:戳这里 题意:给一个树加最少的边,使得1到所有点的距离小于等于2. 解题思路:分析样例3可以看出,如果一个点到1的距离大于2,那么建立1到该点的父亲节点的边将比直接与该点建边更 ...

  10. cccc超级酱油心得

    第一次线下比赛献给了cccc. 大致写写自己心得,比赛前一天晚上日常和室友在宿舍玩到11点多,洗漱上床.睡前突然想起第二天还有比赛,顿时激动加紧张.在床上刷了刷知乎和百度,看几道去年的真题,熬到了12 ...