二. Pod介绍
1. 基本感念
在Kubernetes中,Pod是调度的最小元素,它有网络,有存储。一个Pod封装一个或多个应用容器、存储资源、一个独立的网络IP以及管理控制容器运行方式的策略选项。Pod中的每个容器共享网络命名空间(包括IP与端口),Pod内的容器可以使用localhost相互通信。Pod可以指定一组共享存储卷Volumes,Pod中所有容器都可以访问共享的Volumes,Volumes用于数据持久化,防止容器重启丢失数据。
- 单容器Pod,最常见的应用方式。
- 多容器Pod,Kubernetes会保证所有的容器都在同一台物理主机或虚拟主机中运行。多容器Pod是相对高阶的使用方式,除非应用耦合特别严重,一般不推荐使用这种方式。一个Pod内的容器共享IP地址和端口范围,容器之间可以通过 localhost 互相访问。
Pod并不提供保证正常运行的能力,因为可能遭受Node节点的物理故障、网络分区等等的影响,整体的高可用是Kubernetes集群通过在集群内调度Node来实现的。通常情况下我们不要直接创建Pod,一般都是通过Controller来进行管理
Pod存在意义
(1)创建容器使用docker, docker一个容器中包含一个进程,一个进程对应一个应用程序。Pod是多进程设计,运行多个容器,多个应用程序。
(2)Pod存在为了亲密性应用
- 两个应用之间进行交互
- 网络之间调用
- 两个应用需要频繁调用
2. Pod的生命周期
像单独的容器应用一样,Pod并不是持久运行的。Pod创建后,Kubernetes为其分配一个UID,并且通过Controller调度到Node中运行,然后Pod一直保持运行状态直到运行正常结束或者被删除。在Node发生故障时,Controller负责将其调度到其他的Node中。Kubernetes为Pod定义了几种状态,分别如下:
- Pending,Pod已创建,正在等待容器创建。经常是正在下载镜像,因为这一步骤最耗费时间。
- Running,Pod已经绑定到某个Node并且正在运行。或者可能正在进行意外中断后的重启。
- Succeeded,表示Pod中的容器已经正常结束并且不需要重启。
- Failed,表示Pod中的容器遇到了错误而终止。
- Unknown,因为网络或其他原因,无法获取Pod的状态。
3. 如何对Pod进行健康检查
Kubernetes利用Handler功能,可以对容器的状况进行探测,有以下三种形式。
- ExecAction:在容器中执行特定的命令。
- TCPSocketAction:检查容器端口是否可以连接。
- HTTPGetAction:检查HTTP请求状态是否正常。
4. Pod带来的好处
- Pod做为一个可以独立运行的服务单元,简化了应用部署的难度,以更高的抽象层次为应用部署管提供了极大的方便。
- Pod做为最小的应用实例可以独立运行,因此可以方便的进行部署、水平扩展和收缩、方便进行调度管理与资源的分配。
- Pod中的容器共享相同的数据和网络地址空间,Pod之间也进行了统一的资源管理与分配。
5. 常用Pod管理命令
Pod的配置信息中有几个重要部分,apiVersion、kind、metadata、spec以及status。其中apiVersion和kind是比较固定的,status是运行时的状态,所以最重要的就是metadata和spec两个部分。
以下为demo配置文件, demo.yml
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
labels:
app: bash
tir: backend
spec:
containers:
- name: bash-container
image: docker.io/busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
5.1 创建
利用kubectl命令行管理工具,我们可以直接在命令行通过配置文件创建。如果安装了Dashboard图形管理界面,还可以通过图形界面创建Pod。因为最终Pod的创建都是落在命令上的,这里只介绍如何使用kubectl管理工具来创建。
使用配置文件的方式创建Pod。
kubectl create -f demo.yml
5.2 查看配置
如果想了解一个正在运行的Pod的配置,可以通过以下命令获取。
kubectl get pod first-pod -o yaml
5.3 查看日志
kubectl logs demo-pod
如果Pod中有多个容器,查看特定容器的日志需要指定容器名称
kubectl logs pod-name -c container-name
5.4 标签管理
标签是Kubernetes管理Pod的重要依据,我们可以在demo.yaml文件中 metadata 中指定,也可以通过命令行进行管理。
- 显示Pod的标签
kubectl get pods --show-labels
- 根据标签来查询Pod
kubectl get pods -l tir=backend --show-labels
- 增加标签
kubectl label pod demo-pod tir=frontend
- 修改标签
kubectl label pod demo-pod tir=unkonwn --overwrite
- 可以将标签显示为列
kubectl get pods -L app,tir
标签是Kubernetes中非常强大的一个功能,Node节点也可以增加标签,再利用Pod的标签选择器,可以将Pod分配到不同类型的Node上。
5.5 删除Pod
kubectl delete pods demo-pod
也可以根据标签选择器删除
kubectl delete pods -l tir=backend
6. Pod Preset
利用这个特性,可以在Pod启动过程中向Pod中注入密码 Secrets、存储 Volumes、挂载点 Volume Mounts和环境变量。通过标签选择器来指定Pod。利用这个特性,Pod Template的维护人员就不需要为每个Pod显示的提供相关的属性。
具体的工作步骤
- 检查所有可用的ProdPresets
- 检查是否有ProdPreset的标签与即将创建的Pod相匹配
- 将PodPreset中定义的参数与Pod定义合并
- 如果参数合并出错,则丢弃ProPreset参数,继续创建Pod
- 为Pod增加注解,表示层被ProdPreset修改过,形式为
podpreset.admission.kubernetes.io/podpreset-<pod-preset name>: "<resource version>"
对于 Env、EnvFrom、VolumeMounts Kubernetes修改Container Spec,对于Volume修改Pod Spec。
7. Pod 中断
7.1 计划内中断
- 删除部署 Deployment或者其他控制器
- 更新部署模版导致的Pod重启
- 直接删除Pod
- 集群的缩容
- 手工移除
7.2 计划外中断
- 硬件故障、物理节点宕机
- 集群管理员误删VM
- 云供应商故障导致的主机不可用
- Kernel panic
- 集群网络分区导致节点消失
- 资源耗尽导致的节点剔除
8. Pod 调度策略
- Pod资源限制
sepc
containers:
- name: db
image: mysql
resources:
requests: #调度限制,根据request找到足够的node节点进行调度
memory: "64Mi"
cpu: "250m"
limits: #最大限制0
memory: "128Mi"
cpu: "500m"
- 节点选择器标签调度
sepc
nodeSelector:
env_role:dev #k8s标签
- 节点亲和性调度
- 基于Taint(污点)驱逐