Kubernetes Pod使用
Pod使用
Pod是kubernetes中你可以创建和部署的最小也是最简的单位。一个Pod代表着集群中运行的一个
进程。
Pod中封装着应用的容器(有的情况下是好几个容器),存储、独立的网络IP,管理容器如何运行的策略选项。Pod代表着部署的一个单位:kubernetes中应用的一个实例,可能由一个或者多个容器组合在一起共享资源。
Pod的特点
Pod中共享的环境包括Linux的namespace,cgroup和其他可能的隔绝环境,这一点跟Docker容器一致。在Pod的环境中,每个容器中可能还有更小的子隔离环境。
Pod中的容器共享IP地址和端口号,它们之间可以通过127.0.0.1互相发现。它们之间可以通过进程间通信,需要明白的是同一个Pod下的容器是通过lo网卡进行通信。
Pod中的容器也有访问共享volume的权限,这些volume会被定义成pod的一部分并挂载到应用容器的文件系统中。
就像每个应用容器,pod被认为是临时实体。在Pod的生命周期中,pod被创建后,被分配一个唯一的ID(UID),调度到节点上,并一致维持期望的状态直到被终结(根据重启策略)或者被删除。
如果node死掉了,分配到了这个node上的pod,在经过一个超时时间后会被重新调度到其他node节点上。一个给定的pod(如UID定义的)不会被“重新调度”到新的节点上,而是被一个同样的pod取代,如果期望的话甚至可以是相同的名字,但是会有一个新的UID(查看replication controller获取详情)。
Pod如何管理容器
Pod中可以同时运行多个进程(作为容器运行)协同工作。同一个Pod中的容器会自动的分配到同一个 node 上。同一个Pod中的容器共享资源、网络环境和依赖,它们总是被同时调度
注意在一个Pod中同时运行多个容器是一种比较高级的用法。只有当你的容器需要紧密配合协作的时候才考虑用这种模式。例如,你有一个容器作为web服务器运行,需要用到共享的volume,有另一个“sidecar”容器来从远端获取资源更新这些文件,如下图所示:
Pod共享资源
网络
每一个Pod都会被指派一个唯一的Ip地址,在Pod中的每一个容器共享网络命名空间,包括Ip地址和网络端口。在同一个Pod中的容器可以同locahost进行互相通信。当Pod中的容器需要与Pod外的实体进行通信时,则需要通过端口等共享的网络资源。
每个Pod对象都会被分配一个集群内专用的IP地址,也称为Pod IP,同一Pod内部的所有容器共享Pod对象的Network和UTS名称空间,其中包括主机名、IP地址和端口等。因此,这些容器间的通信可以基于本地回环接口lo进行,而与Pod外的其他组件的通信则需要使用Service资源对象的ClusterIP及相应的端口完成。
存储卷
Pod能够被指定共享存储卷的集合,在Pod中所有的容器能够访问共享存储卷,允许这些容器共享数据。存储卷也允许在一个Pod持久化数据,以防止其中的容器需要被重启。
用户可以为Pod对象配置一组“存储卷”资源,这些资源可以共享给其内部的所有容器使用,从而完成容器间数据的共享。存储卷还可以确保在容器终止后重启,甚至是被删除后也能确保数据不会丢失,从而保证了生命周期内的Pod对象数据的持久化存储。
使用方式
在Kubrenetes集群中Pod有如下两种使用方式:
自主式Pod
这种Pod本身是不能自我修复的,当Pod被创建后(不论是由你直接创建还是被其他Controller),
都会被Kuberentes调度到集群的Node上。直到Pod的进程终止、被删掉、因为缺少资源而被驱逐、或者Node故障之前这个Pod都会一直保持在那个Node上。Pod不会自愈。如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除。同样的,如果Pod所在Node缺少资源或者Pod处于维护状态,Pod也会被驱逐。
控制器管理的Pod
Kubernetes使用更高级的称为Controller的抽象层,来管理Pod实例。Controller可以创建和管理
多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。例如,如果一个Node故障,Controller就能自动将该节点上的Pod调度到其他健康的Node上。虽然可以直接使用Pod,但是在Kubernetes中通常是使用Controller来管理Pod的
自主运行Pod
创建资源清单
通过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
参数描述
下面简要分析一下上面的Pod定义文件:
- apiVersion: 使用哪个版本的Kubernetes API来创建此对象
- kind:要创建的对象类型,例如Pod,Deployment等
- metadata:用于唯一区分对象的元数据,包括:name,UID和namespace
- labels:是一个个的key/value对,定义这样的label到Pod后,其他控制器对象可以通过这样的label来定位到此Pod,从而对Pod进行管理。(参见Deployment等控制器对象)
- spec: 其它描述信息,包含Pod中运行的容器,容器中运行的应用等等。不同类型的对象拥有不同的spec定义。详情参见API文档
创建Pod
使用kubectl创建pod
kubectl apply -f nginx-pod.yml
Pod操作
查看Pod列表
kubectl get pods
可以通过增加 -o wide查看详细信息
kubectl get pods -o wide
查看描述信息
可以通过describe查看pod的详细信息
kubectl describe pod nginx
访问pod
可以通过k8s创建的虚拟IP进行访问,可以在k8s的任何一个节点访问
curl 10.244.1.10
删除Pod
可以使用delete删除Pod,删除后不能进行恢复
kubectl delete pod nginx
控制器运行Pod
Pod本身不具备容错性,这意味着如果Pod运行的Node宕机了,那么该Pod无法恢复。因此推荐使用Deployment等控制器来创建Pod并管理。
创建资源清单
通过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
参数描述
下面简要分析一下上面的Pod定义文件:
Replicas 副本数量
spec.replicas 是可以选字段,指定期望的pod数量,默认是1。
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。
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 , 如果不指定的话这就是默认配置。
创建Pod
kubectl apply -f nginx-pod.yml
kubectl get pods -o wide
创建后发现,有两个nginx的pod在运行,符合我们的预期
Pod操作
删除Pod
这里可以尝试删除Pod
kubectl delete pod nginx-deployment-f77774fc5-cgs82
#查看Pod详情
kubectl get pods -o wide
删除Pod后发现重新新建了一个Pod,这是因为有控制器发现少了一个Pod就会进行重新拉起来一个
镜像拉取策略
pod的镜像拉取策略分为三种:
- always(总是从官方下载镜像)
- never(从不下载镜像)
- ifnotpresent(如果本地没有镜像就从官方下载镜像)。
Kubernetes集群默认使用IfNotPresent策略
always
不管是否存在本地镜像,总是从远程仓库下载
修改资源清单
我们可以通过修改配置清单来配置不同的策略
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
生效配置
kubectl apply -f nginx-pod.yml
查看创建过程
kubectl describe pod nginx-deployment
可以清楚的看到重新下载而没有使用本地镜像
IfNotPresent
Kubernetes集群的默认策略,如果有本地镜像就使用,没有则从远程仓库下载
修改资源清单
我们可以通过修改配置清单来配置不同的策略
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
生效配置
kubectl apply -f nginx-pod.yml
查看创建过程
kubectl describe pod nginx-deployment
可以清楚的看到没有重新下载镜像而是使用本地的镜像。