【云原生kubernetes】k8s中pod使用详解
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
一、前言
在之前k8s组件一篇中我们谈到了pod这个组件了解到pod是k8s中资源管理的最小单位可以说Pod是整个k8s对外提供服务的最基础的个体有必要对Pod做深入的学习和探究。
二、再看k8s架构图
为了加深对k8s中pod的理解再来回顾下k8s的完整架构
三、pod特点
结合上面这张图关于pod可以总结下面几点
- Pod是一组容器, 是K8S中最小的单位,一个Pod可包含多个容器但通常情况下每个Pod中仅运行一个容器可以把Pod理解成豌豆荚, Pod内的每个容器就像是一颗豌豆
- Pod 的核心是运行容器必须指定容器引擎比如 Docker是其中一种技术
四、pod分类
根据pod是否自主创建可以分为两种
- 自主创建直接创建出来的Pod这种pod删除后就没有了也不会自动重建
- 控制器创建通过控制器创建的pod这类Pod删除了之后还会自动重建
五、pod中的容器
从上图可以发现容器是运行在pod中的也可以简单理解为pod是容器运行的外部容器所以一个pod理论上可以运行很多个docker容器关于这一点做两点说明
- 每个Pod中一个容器的模式是最常见的用法Pod是容器的简单封装K8S管理Pod而不是直接管理容器
- 一个Pod中同时运行多个需要互相协作的容器它们共享资源同一个Pod中的容器可以作为service单位
六、Pod中的网络
对于k8s集群中的某个节点来说可能部署了多个pod这些不同的pod之间如果也需要互相通信怎么办呢这就需要说到pod中的网络了
- 一个 pod 包含一组容器一个 pod 不会跨越多个工作节点
- 每个Pod都会被分配一个唯一的IP地址Pod中的所 有容器共享网络空间包括IP地址和端口
- Pod内 部的容器可以使用localhost互相通信
补充k8s中的网络通信模型
K8S集群的有4种网络
具体如下同一pod内的容器间通信、各pod彼此之间的通信、pod与service间的通信、以及集群外部的流量同service之间的通信
七、Pod中的存储
- Volume 也可以用来持久化Pod中的存储资源以防容器重启后文件丢失
- Pod中 的所有容器都可以访问共享的Volume
八、Pod常用操作命令
1、查看k8s集群中系统运行的pod
kubectl get pod -n kube-system
2、查看创自己创建的pod
kubectl get pod
或
kubectl get pod,svc,deploy
3、删除pod
直接删除pod
kubectl delete pod pod名称 -n 名称空间
删除通过控制器创建的pod
kubectl delete pod控制器名称 -n 名称空间
补充说明
- 如果是通过deploy控制器创建的pod, 直接删除则会自动创建新的
- -n 非必须表示某个具体的命名空间
4、启动一个pod【命令方式启动】
kubectl run pod名称 --image=镜像 --port=80 --namespace 命名空间名字
比如在上一篇中我们创建了一个nginx的pod可以写成
kubectl run test-nignx-pod --image=nginx:1.23.0 --port=80 --namespace test
5、启动一个pod【yaml方式启动】
在当前目录下创建一个yaml的文件
配置内容如下
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
chapter: first-app
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name : nginx
image: nginx:1.23.0
ports:
- containerPort: 80
然后使用apply的方式启动
kubectl apply -f ./test-nginx.yaml
注意点
通过 apply -f 的方式创建的pod删除的时候也需要通过apply -f 的方式删除
6、通过deployment控制器导出yaml文件
在当前集群下我们有下面这个pod
使用下面的命令导出这个pod对应的yaml
kubectl create deployment test-nginx3 --image=nginx:1.23.0 --namespace test -o yaml --dry-run=client > ./nginx.yaml
执行之后可以发现在当前目录下创建了一个yaml的文件
文件内容是不是和前面我们自己创建的那个yaml很像看起来似乎更加完整需要注意的是这个里面的有些参数是可以手动修改的比如replicas 这个表示生成的nginx的pod个数
然后就可以使用apply的命令创建pod了
kubectl apply -f nginx.yaml
7、查看某个名称空间下 pod 的详细信息
kubectl get pod -n ns名称 -o wide
比如查看default名称空间下的pod信息就能看到上面通过yaml文件创建的pod
kubectl get pod -n default -o wide
通过k8s创建出来的pod会分给当前的pod一个IP地址可以直接通过curl 进行访问【同一个集群下的其他节点都可访问】
九、Pod延伸补充说明
1、pod镜像拉取策略
pod镜像拉取策略可以通过imagePullPolicy字段配置镜像拉取策略如下
spec:
containers:
- name: nginx
image: nginx:1.23.0
imagePullPolicy: Always #可取 Always默认值、IfNotPresent、Never
imagePullPolicy可以使用以下3种策略值
Always: 默认值每次创建pod都会重新拉取一次镜像;
IfNotPresent: 镜像在宿主机上不存在时才拉取;
Never: 永远不会主动拉取镜像使用本地镜像需要你手动拉取镜像下来;
2、pod使用资源限制配置
我们知道集群中的节点都是有一定的配置的比如CPU,内存等信息总不能因为创建的某个pod把节点的资源给打满了因此可以在配置文件中进行配置以使用apply -f 的方式创建一个pod配置文件中关键配置如下
resources
requests
memory"内存大小"
cpu"cpu占用大小"
limits:
memory"内存占用大小"
cpu"cpu占用大小"
下面是一段完整的标签配置和说明
spec:
containers:
- name: string #必选容器名称
image: string #必选容器的镜像名称
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: string #Cpu的限制单位为core数将用于docker run --cpu-shares参数
memory: string #内存限制单位可以为Mib/Gib将用于docker run --memory参数
requests: #资源请求的设置
cpu: string #Cpu请求容器启动的初始可用数量
memory: string #内存请求,容器启动的初始可用数量
如下为一段实际使用中的配置
更多配置请参考文档k8s文档
3、关于pod的创建流程
以通过kubectl apply -f xxx.yaml 这种方式创建的pod进行说明结合本文开头的k8s架构图
- kubectl向apiserver发送创建pod的请求
- apiserver把pod的创建信息存储到etcd进行保存
- scheduler监听到未绑定node的pod资源通过调度算法对该pod资源选定一个合适的node进行绑定然后响应给apiserver更新pod状态并存储到etcd中
- 在绑定的node中Controller-Manager通知kubelet收到分配到自身节点上的pod调用容器引擎api创建容器并把容器状态响应给apiserver
4、Pod调度策略
默认情况下一个Pod在哪个Node节点上运行是由Scheduler组件采用相应的算法计算出来的这个过程是不受人工控制的。但是在实际使用中这并不满足的需求因为很多情况下我们想控制某些Pod到达某些节点上那么应该怎么做呢这就要求了解k8s对Pod的调度规则 。
下面列举几个影响pod调度的因素
pod资源限制
scheduler根据requests找到足够大小的node进行调度
使用节点选择器标签nodeSelector
节点选择器可以将节点分开比如k8s集群中有多个节点为了区分生产开发和测试环境就可以利用节点选择器标签进行划分
例如当前需要把pod调度到开发环境中则可以通过scheduler将pod调度到标签选择器中为env_role:dev的node中 对应的yaml核心配置如下
nodeSelector:
env_role:dev/prod
关于节点选择器后续还会通过一文详细讲解其使用。