架构师系列-k8s(二)-k8s组件介绍及POD使用
我们把一个有效的 Kubernetes 部署称为集群,您可以将 Kubernetes 集群可视化为两个部分:控制平面与计算设备(或称为节点),每个节点都是其自己的 Linux环境,并且可以是物理机或虚拟机,每个节点都运行由若干容器组成的容器集。
3.1 整体架构
下图清晰表明了 Kubernetes 的架构设计以及组件之间的通信协议。
3.1.1 Master 架构
3.1.2 Node 架构
3.2 k8s部署组件介绍
我们把一个有效的 Kubernetes 部署称为集群,您可以将 Kubernetes 集群可视化为两个部分:
控制平面与计算设备(或称为节点),每个节点都是其自己的 Linux环境,并且可以是物理机或虚拟机,每个节点都运行由若干容器组成的容器集。
3.2.1 K8s 集群架构图
以下 K8s 架构图显示了 Kubernetes 集群的各部分之间的联系:
3.2.2 k8s控制组件
3.2.2.1 控制平面
K8s 集群的神经中枢
让我们从 Kubernetes 集群的神经中枢(即控制平面)开始说起。在这里,我们可以找到用于控制集群的 Kubernetes 组件以及一些有关集群状态和配置的数据,这些核心 Kubernetes 组件负责处理重要的工作,以确保容器以足够的数量和所需的资源运行。
控制平面会一直与您的计算机保持联系。集群已被配置为以特定的方式运行,而控制平面要做的就是确保万无一失。
3.2.2.2 kube-apiserver
K8s 集群API,如果需要与您的 Kubernetes 集群进行交互,就要通过 API
Kubernetes API 是 Kubernetes 控制平面的前端,用于处理内部和外部请求。API 服务器会确定请求是否有效,如果有效,则对其进行处理,您可以通过 REST 调用、kubectl 命令行界面或其他命令行工具(例如 kubeadm)来访问 API。
3.2.2.3 kube-scheduler
K8s 调度程序,您的集群是否状况良好?如果需要新的容器,要将它们放在哪里?这些是 Kubernetes 调度程序所要关注的问题。
调度程序会考虑容器集的资源需求(例如 CPU 或内存)以及集群的运行状况。随后,它会将容器集安排到适当的计算节点。
3.2.2.4 kube-controller-manager
K8s 控制器,控制器负责实际运行集群,而 Kubernetes 控制器管理器则是将多个控制器功能合而为一
控制器用于查询调度程序,并确保有正确数量的容器集在运行。如果有容器集停止运行,另一个控制器会发现并做出响应。控制器会将服务连接至容器集,以便让请求前往正确的端点。还有一些控制器用于创建帐户和 API 访问令牌。
3.2.2.5 etcd
键值存储数据库
配置数据以及有关集群状态的信息位于 etcd(一个键值存储数据库)中。etcd 采用分布式、容错设计,被视为集群的最终事实来源。
3.2.3 k8s运行组件
3.2.3.1 k8s节点
Kubernetes 集群中至少需要一个计算节点,但通常会有多个计算节点。
容器集经过调度和编排后,就会在节点上运行。如果需要扩展集群的容量,那就要添加更多的节点。
3.2.3.2 容器集
容器集是 Kubernetes 对象模型中最小、最简单的单元。
它代表了应用的单个实例。每个容器集都由一个容器(或一系列紧密耦合的容器)以及若干控制容器运行方式的选件组成。容器集可以连接至持久存储,以运行有状态应用。
3.2.3.3 容器运行时引擎
为了运行容器,每个计算节点都有一个容器运行时引擎。
比如 Docker,但 Kubernetes 也支持其他符合开源容器运动(OCI)标准的运行时,例如 rkt 和 CRI-O。
3.2.3.4 kubelet
每个计算节点中都包含一个 kubelet,这是一个与控制平面通信的微型应用。
kublet 可确保容器在容器集内运行,当控制平面需要在节点中执行某个操作时,kubelet 就会执行该操作。
3.2.3.5 kube-proxy
每个计算节点中还包含 kube-proxy,这是一个用于优化 Kubernetes 网络服务的网络代理。
kube-proxy 负责处理集群内部或外部的网络通信——靠操作系统的数据包过滤层,或者自行转发流量。
3.2.4 k8s 存储组件
3.2.4.1 持久存储
除了管理运行应用的容器外,Kubernetes 还可以管理附加在集群上的应用数据。
Kubernetes 允许用户请求存储资源,而无需了解底层存储基础架构的详细信息。持久卷是集群(而非容器集)所特有的,因此其寿命可以超过容器集。
3.2.4.2 容器镜像仓库
Kubernetes 所依赖的容器镜像存储于容器镜像仓库中。
这个镜像仓库可以由您自己配置的,也可以由第三方提供。
3.2.4.3 底层基础架构
您可以自己决定具体在哪里运行 Kubernetes。
答案可以是裸机服务器、虚拟机、公共云提供商、私有云和混合云环境。Kubernetes 的一大优势就是它可以在许多不同类型的基础架构上运行。
3.3 k8s安装部署
4 Pod使用
Pod是kubernetes中你可以创建和部署的最小也是最简的单位,一个Pod代表着集群中运行的一个进程。
Pod中封装着应用的容器(有的情况下是好几个容器),存储、独立的网络IP,管理容器如何运行的策略选项,Pod代表着部署的一个单位:kubernetes中应用的一个实例,可能由一个或者多个容器组合在一起共享资源。
4.1 Pod 特点
Pod有两个必须知道的特点
4.1.1 网络
每一个Pod都会被指派一个唯一的Ip地址,在Pod中的每一个容器共享网络命名空间,包括Ip地址和网络端口,在同一个Pod中的容器可以同locahost进行互相通信,当Pod中的容器需要与Pod外的实体进行通信时,则需要通过端口等共享的网络资源。
4.1.2 存储
Pod能够配置共享存储卷,在Pod中所有的容器能够访问共享存储卷,允许这些容器共享数据,存储卷也允许在一个Pod持久化数据,以防止其中的容器需要被重启。
4.2 使用方式
4.2.1 自主式Pod
这种Pod本身是不能自我修复的,当Pod被创建后(不论是由你直接创建还是被其他Controller),都会被Kuberentes调度到集群的Node上,直到Pod的进程终止、被删掉、因为缺少资源而被驱逐、或者Node故障之前这个Pod都会一直保持在那个Node上,Pod不会自愈。
如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除,同样的,如果Pod所在Node缺少资源或者Pod处于维护状态,Pod也会被驱逐。
4.2.2 控制器管理的Pod
Kubernetes使用更高级的称为Controller的抽象层,来管理Pod实例,Controller可以创建和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。
例如,如果一个Node故障,Controller就能自动将该节点上的Pod调度到其他健康的Node上。虽然可以直接使用Pod,但是在Kubernetes中通常是使用Controller来管理Pod的
4.3 自主运行Pod
4.3.1 创建资源清单
通过yaml文件或者json描述Pod和其内容器的运行环境和期望状态,例如一个最简单的运行nginx应用的pod,定义如下
vi nginx-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.12
ports:
- containerPort: 80
4.3.1.1 参数描述
下面简要分析一下上面的Pod定义文件:
- apiVersion: 使用哪个版本的Kubernetes API来创建此对象
- kind:要创建的对象类型,例如Pod,Deployment等
- metadata:用于唯一区分对象的元数据,包括:name,UID和namespace
- labels:是一个个的key/value对,定义这样的label到Pod后,其他控制器对象可以通过这样的label来定位到此Pod,从而对Pod进行管理。(参见Deployment等控制器对象)
- spec: 其它描述信息,包含Pod中运行的容器,容器中运行的应用等等。不同类型的对象拥有不同的spec定义。详情参见API文档
4.3.2 创建Pod
使用
kubectl
创建pod
kubectl apply -f nginx-pod.yml
4.3.3 Pod操作
4.3.3.1 查看Pod列表
kubectl get pods
可以通过增加
-o wide
查看详细信息
kubectl get pods -o wide
4.3.3.2 查看描述信息
可以通过
describe
查看pod的详细信息
kubectl describe pod nginx
4.3.3.3 访问pod
可以通过
k8s
创建的虚拟IP进行访问,可以在k8s的任何一个节点访问
curl 10.244.1.10
4.3.3.4 删除Pod
可以使用
delete
删除Pod,删除后不能进行恢复
kubectl delete pod nginx
4.4 控制器运行Pod
Pod本身不具备容错性,这意味着如果Pod运行的Node宕机了,那么该Pod无法恢复,因此推荐使用Deployment等控制器来创建Pod并管理。
4.4.1 创建资源清单
通过yaml文件或者json描述Pod和其内容器的运行环境和期望状态,例如一个最简单的运行nginx应用的pod,定义如下
vi nginx-pod.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.12
ports:
- containerPort: 80
4.4.2 参数描述(了解)
下面简要分析一下上面的Pod定义文件:
4.4.2.1 Replicas
副本数量
spec.replicas 是可以选字段,指定期望的pod数量,默认是1。
4.4.2.2 Selector
标签选择器
.spec.selector是可选字段,用来指定 label selector ,圈定Deployment管理的pod范围。如果被指定, .spec.selector 必须匹配 .spec.template.metadata.labels,否则它将被API拒绝。如果 .spec.selector 没有被指定, .spec.selector.matchLabels 默认是.spec.template.metadata.labels。
在Pod的template跟.spec.template不同或者数量超过了.spec.replicas规定的数量的情况下,Deployment会杀掉label跟selector不同的Pod。
4.4.2.3 Pod Template
Pod模板,.spec.template 是 .spec中唯一要求的字段。
.spec.template 是 pod template,它跟 Pod有一模一样的schema,除了它是嵌套的并且不需要apiVersion 和 kind字段。
另外为了划分Pod的范围,Deployment中的pod template必须指定适当的label(不要跟其他controller重复了,参考selector)和适当的重启策略。
.spec.template.spec.restartPolicy 可以设置为 Always , 如果不指定的话这就是默认配置。
4.4.3 创建Pod
kubectl apply -f nginx-pod.yml
kubectl get pods -o wide
创建后发现,有两个nginx的pod在运行,符合我们的预期
4.4.4 Pod操作
4.4.4.1 删除Pod
这里可以尝试删除Pod
kubectl delete pod nginx-deployment-f77774fc5-cgs82
# 查看Pod详情
kubectl get pods -o wide
删除Pod后发现重新新建了一个Pod,这是因为有控制器发现少了一个Pod就会进行重新拉起来一个
4.5 镜像拉取策略
pod的镜像拉取策略分为三种:
- always(总是从官方下载镜像)
- never(从不下载镜像)
- ifnotpresent(如果本地没有镜像就从官方下载镜像)。
Kubernetes集群默认使用IfNotPresent策略
4.5.1 always
不管是否存在本地镜像,总是从远程仓库下载
4.5.1.1 修改资源清单
我们可以通过修改配置清单来配置不同的策略
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.12
imagePullPolicy: Always
ports:
- containerPort: 80
4.5.1.2 生效配置
kubectl apply -f nginx-pod.yml
4.5.1.3 查看创建过程
kubectl describe pod nginx-deployment
可以清楚的看到重新下载而没有使用本地镜像
4.5.2 IfNotPresent
Kubernetes集群的默认策略,如果有本地镜像就使用,没有则从远程仓库下载
4.5.2.1 修改资源清单
我们可以通过修改配置清单来配置不同的策略
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.12
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
4.5.2.2 生效配置
kubectl apply -f nginx-pod.yml
4.5.2.3 查看创建过程
kubectl describe pod nginx-deployment
可以清楚的看到没有重新下载镜像而是使用本地的镜像。
5. Pod生命周期
5.1 各个阶段
POD中明确规定了如下几个阶段
状态值 | 说明 |
---|---|
挂起(Pending) | Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建,等待时间包括调度 Pod 的时间和通过网络下载镜像的时间。 |
运行中(Running) | 该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。 |
成功(Succeeded) | Pod 中的所有容器都被成功终止,并且不会再重启。 |
失败(Failed) | Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。 |
未知(Unknown) | 因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。 |
实际上还有一中状态Terminating,在代码和文档中都没有说明,但却是存在。这种情况出现杂无法获取所在主机的资源情况,一直在尝试建立连接。
5.2 Pod重启策略
在Pod中的容器可能会由于异常等原因导致其终止退出,Kubernetes提供了重启策略以重启容器。
Pod通过restartPolicy
字段指定重启策略,重启策略类型为:Always、OnFailure 和 Never,默认为 Always。
重启策略对同一个Pod的所有容器起作用,容器的重启由Node上的kubelet执行。Pod支持三种重启策略,在配置文件中通过restartPolicy
字段设置重启策略:
重启策略 | 说明 |
---|---|
Always | 当容器失效时,由kubelet自动重启该容器 |
OnFailure | 当容器终止运行且退出码不为0时,由kubelet自动重启该容器 |
Never | 不论容器运行状态如何,kubelet都不会重启该容器 |
注意:这里的重启是指在Pod的宿主Node上进行本地重启,而不是调度到其它Node上。
5.3 Pod状态转换
Pod的容器数 | Pod当前状态 | 发生的事件 | Pod结果状态 | ||
---|---|---|---|---|---|
RestartPolicy=Always | RestartPolicy=OnFailure | RestartPolicy=Never | |||
包含一个容器 | Running | 容器成功退出 | Running | Succeeded | Succeeded |
包含一个容器 | Running | 容器失败退出 | Running | Running | Failure |
包含两个容器 | Running | 1个容器失败退出 | Running | Running | Running |
包含两个容器 | Running | 容器被OOM杀掉 | Running | Running | Failure |
5.4 生命周期行为
5.4.1 初始化容器
初始化容器(
init container
)即应用程序的主容器启动之前要运行的容器,常用于为主容器执行一些预置操作,它们具有两种典型特征。
- 初始化容器必须运行完成直至结束,若某初始化容器运行失败,那么
kubernetes
需要重启它直到成功完成。(注意:如果pod
的spec.restartPolicy
字段值为“Never
”,那么运行失败的初始化容器不会被重启。) - 每个初始化容器都必须按定义的顺序串行运行。
5.4.2 容器探测
容器探测(
container probe
)是Pod
对象生命周期中的一项重要的日常任务,它是kubelet
对容器周期性执行的健康状态诊断,诊断操作由容器的处理器(handler
)进行定义,Kubernetes
支持三种处理器用于Pod
探测:
ExecAction
:在容器内执行指定命令,并根据其返回的状态码进行诊断的操作称为Exec
探测,状态码为0
表示成功,否则即为不健康状态。TCPSocketAction
:通过与容器的某TCP
端口尝试建立连接进行诊断,端口能够成功打开即为正常,否则为不健康状态。HTTPGetAction
:通过向容器IP
地址的某指定端口的指定path
发起HTTP GET
请求进行诊断,响应码为2xx
或3xx
时即为成功,否则为失败。
任何一种探测方式都可能存在三种结果:
“Success”(成功)
、“Failure”(失败)
、“Unknown”(未知)
,只有success
表示成功通过检测。
更多推荐
所有评论(0)