本文重点介绍k8s中所涉及的核心概念,能够帮助读者快速地从整体方面了解k8s,便于初学者在实际工作中从事相关工作!
Docker 和K8s
Docker是应用最广泛的容器技术,它通过打包镜像、启动容器来创建服务。
k8s的全称 kubernetes。它是一个完整的分布式系统支撑平台,集群管理功能齐全。
Kubernetes同时提供完善的管理工具,涵盖了开发、部署、测试、运行监控等各个环节。
随着应用的日益复杂,容器的数量也不断增加,由此衍生出管理运维容器这一重要问题。随着云计算的发展,容器的漂移也是云端最大的挑战。k8s正是在这种业务的驱动下,提出了一套全新的基于容器技术的分布式架构领先方案,这是容器技术领域中一个重大突破和创新。
简单地理解k8s可以管理运维容器(docker) 下图是k8s的整体架构:
k8s中的重要概念
Master 节点
Master 节点负责对集群中所有容器的调度,各种资源对象的控制,以及响应集群的所有请求。
Node 节点
Node 节点是 Kubernetes 的工作节点,负责运行业务容器。
集群(Cluster)
集群是一组被 Kubernetes 统一管理和调度的节点,被 Kubernetes 纳管的节点可以是物理机或者虚拟机。集群其中一部分节点作为 Master 节点,负责集群状态的管理和协调,另一部分作为 Node 节点,负责执行具体的任务,实现用户服务的启停等功能。
标签(Label)
Label 是一组键值对,每一个资源对象都会拥有此字段。Kubernetes 中使用 Label 对资源进行标记,然后根据 Label 对资源进行分类和筛选。
命名空间(Namespace)
Kubernetes 中通过命名空间来实现资源的虚拟化隔离,将一组相关联的资源放到同一个命名空间内,避免不同租户的资源发生命名冲突,从逻辑上实现了多租户的资源隔离。
容器组(Pod)
Pod 是 Kubernetes 中的最小调度单位,它由一个或多个容器组成,一个 Pod 内地容器共享相同的网络命名空间和存储卷。Pod 是真正的业务进程的载体,在 Pod 运行前,Kubernetes 会先启动一个 Pause 容器开辟一个网络命名空间,完成网络和存储相关资源的初始化,然后再运行业务容器。也就是说每个Pod中都运行着一个特殊的被称为Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络和Volume挂载卷。后面我们会继续对其进行重点讲解。
无状态部署(Deployment)
Deployment 是一组 Pod 的抽象,Deployment用于部署无状态的服务,通过 Deployment 控制器保障用户指定数量的容器副本正常运行,并且实现了滚动更新等高级功能,当我们需要更新业务版本时,Deployment 会按照我们指定策略自动地杀死旧版本的 Pod 并且启动新版本的 Pod。
有状态部署(StatefulSet)
StatefulSet本质上是Deployment的一种变体用于部署有状态的服务,它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。
任务(Job)
Job 可以帮助我们创建一个 Pod 并且保证 Pod 的正常退出,如果 Pod 运行过程中出现了错误,Job 控制器可以帮助我们创建新的 Pod,直到 Pod 执行成功或者达到指定重试次数。一种简单的使用场景下,你会创建一个 Job 对象以一种可靠的方式运行某 Pod 直到完成。 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。
服务(Service)
Service 是一组 Pod 访问配置的抽象。每个pod有自己的ip地址,当有多个pod提供相同的服务的时候,就需要有负载均衡的能力,这里就引入了service。
Pod
Pod的理解
Pod:k8s管理的最小单位,包括一个或多个容器,是提供实际业务服务的组件。一个Pod封装一个应用容器(也可以有多个容器),存储资源、一个独立的网络IP以及管理控制容器运行方式的策略选项。Pod代表部署的一个单位:Kubernetes中单个应用的实例,它可能由单个容器或多个容器共享组成的资源。
Pod中运行一个容器。“one-container-per-Pod”模式是Kubernetes最常见的用法; 在这种情况下,你可以将Pod视为单个封装的容器,但是Kubernetes是直接管理Pod而不是容器。Pods中运行多个需要一起工作的容器。Pod可以封装紧密耦合的应用,它们需要由多个容器组成,它们之间能够共享资源,这些容器可以形成一个单一的内部service单位 - 一个容器共享文件,另一个“sidecar”容器来更新这些文件,如下图所示。Pod将这些容器的存储资源作为一个实体来管理。
Pods提供两种共享资源:网络和存储。
网络
每个Pod被分配一个独立的IP地址,Pod中的每个容器共享网络命名空间,包括IP地址和网络端口。Pod内的容器可以使用localhost相互通信。当Pod中的容器与Pod外部通信时,他们必须协调如何使用共享网络资源(如端口)。
存储
Pod可以指定一组共享存储volumes。Pod中的所有容器都可以访问共享volumes,允许这些容器共享数据。volumes 还用于Pod中的数据持久化,以防其中一个容器需要重新启动而丢失数据。
Pod也是我们在实际工作中接触最多的东东,特别是pod的资源清单(对应的yaml文件),我们在后面会详细介绍。
- ReplicaSet(rs):是Pod的管理控制组件,监控Pod的健康状况,保障Pod按照用户的期望去运行。rs是ReplicationController组件的升级版,增加了标签选择器的范围选择功能。
- Deployment:可管理rs、Pod,实现Pod应用的滚动升级和回滚、扩容和缩容。
- Service:是一种可以访问 Pod逻辑分组的策略, Service通常是通过 Label Selector访问 Pod组。集群中Pod的数量和访问地址可能是变化的,这些Pod中的业务应用需要对外提供服务,可通过Service对外提供统一服务地址,Service通过标签选择器,匹配一组提供服务的Pod,从而对客户端隔离了后端Pod的变化。
Pod生命周期
- pending:pod已经被系统认可了,但是内部的container还没有创建出来。这里包含调度到node上的时间以及下载镜像的时间,会持续一小段时间。
- Running:pod已经与node绑定了(调度成功),而且pod中所有的container已经创建出来,至少有一个容器在运行中,或者容器的进程正在启动或者重启状态。--这里需要注意pod虽然已经Running了,但是内部的container不一定完全可用。因此需要进一步检测container的状态。
- Succeeded:这个状态很少出现,表明pod中的所有container已经成功的terminated了,而且不会再被拉起了。
- Failed:pod中的所有容器都被terminated,至少一个container是非正常终止的。(退出的时候返回了一个非0的值或者是被系统直接终止)
- unknown:由于某些原因pod的状态获取不到,有可能是由于通信问题。
一般情况下pod最常见的就是前两种状态。而且当Running的时候,需要进一步关注container的状态。下面就来看下container的状态有哪些
Pod资源清单定义
- apiVersion: v1 #必选,版本号,例如v1
- kind: Pod #必选,资源类型,例如 Pod
- metadata: #必选,元数据
- name: string #必选,Pod名称
- namespace: string #Pod所属的命名空间,默认为"default"
- labels: #自定义标签列表
- spec: #必选,Pod中容器的详细定义
- containers: #必选,Pod中容器列表
- - name: string #必选,容器名称
- image: string #必选,容器的镜像名称
- imagePullPolicy: [ Always|Never|IfNotPresent ] #获取镜像的策略
- 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 #内存请求,容器启动的初始可用数量
- lifecycle: #生命周期钩子
- postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
- preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
- livenessProbe: #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
- 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的重启策略
- nodeName:
#设置NodeName表示将该Pod调度到指定到名称的node节点上 - nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
- 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的存储卷,挂载集群与定义的secret对象到容器内部
- scretname: string
- items:
- - key: string
- path: string
- configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
- name: string
- items:
- - key: string
- path: string