pod
pod是可以在k8s中创建和管理的、最小的可部署的计算单元
Pod(就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个)容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文(资源)中运行。 Pod 所建模的是特定于应用的 “逻辑主机”,其中包含一个或多个应用容器, 这些容器相对紧密地耦合在一起。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于在同一逻辑主机上运行的云应用。
使用命令行的方式启动nginx的pod
这个命令实际上是创建一个部署控制器,部署控制器去部署nginx容器
kubectl create deployment k8s-nginx --image=nginx -r 3
deploymen
:(部署)控制器
k8s-nginx
:名字
-r 3
:重复3个副本(pod)
用户敲一条kubectl命令背后发生了什么(以上条命令为例)
- 用户通过kubectl去部署一个新的应用程序nginx
- 这条指令会去访问apiserver,apiserver接收到这个请求之后将其存储到数据库etcd中
- 控制器监听etcd中资源的变化,一旦发现资源发生了改变,例如有新的 Deployment 定义,控制器就会开始执行它的逻辑
- 副本控制器发现有新的任务要执行,会去创建新的pod去匹配期望的实例数(3)
- 调度控制器是负责选择在哪个节点上启动新的Pod。它会从集群中的节点中选择一个适合的节点,并将这个信息通过apiserver写入 etcd,然后告知kubelet在该节点上启动Pod
- kubelet是运行在每个节点上的代理,负责与apiserver通信并监控自己节点上的 Pod。一旦收到启动Pod的请求,它会与Docker引擎交互,拉取镜像并启动容器kubelet发现pod之后会喊docker engine去拉镜像,并启动容器来部署他们
- kubeproxy会把pod的网络配置好
使用yaml文件创建启动pod
yaml文件的作用是给k8s的apiserver传参
k8s里的apiserver有规范,内部指定了api的版本,规范里制定了可以使用哪些变量,哪些功能是可以使用的
mkdir /pod
cd /pod
[root@node-1 pod]# cat simple-pod.yaml
apiVersion: v1 # 指定api版本
kind: Pod # 资源类型
metadata: # 元数据,对资源进行描述的数据
name: nginx # pod的元数据,指定pod的名字
spec: # 具体的某个资源对象的详细信息
containers: # 容器
- name: nginx # 容器名字
image: nginx:1.14.2 # 镜像的名字和版本
ports: # 容器监听端口
- containerPort: 80 # 具体端口
kubectl apply -f simple-pod.yaml
通过副本控制器deployment写yaml文件启动pod
[root@master pod]# cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels: # 打标签
app: nginx # 具体标签,一般采用k-v,k可以指定
spec:
replicas: 3 # 指定副本pod的数量
selector: # 选择器,副本控制器去匹配需要启动的容器的配置
matchLabels: # 具体匹配的标签
app: nginx # 根据app的值去找nginx的标签
template: # 启动pod的模板
metadata: # 模板的启动pod的元数据
labels: # 给启动的pod打标签
app: nginx # 具体的标签
spec:
containers:
- name: nginx
image: nginx:1.14.2
imagePullPolicy: IfNotPresent # 如果就像不存在就去下载
ports:
- containerPort: 80
kubectl apply -f nginx-deployment.yaml
自己写一个yaml文件创建pod
如果是创建一个pod,api类型就选择v1
[root@master pod2]# kubectl explain pod
KIND: Pod
VERSION: v1
# 查看metadata源数据里面可以写什么,也可以不写
[root@master pod2]# kubectl explain pod.metadata
# 查看containers
[root@master pod2]# kubectl explain pod.spec.containers
# 查看端口
[root@master pod2]# kubectl explain pod.spec.containers.ports
# 查看命名空间
[root@master pod2]# kubectl explain namespace
写一个简单的yaml文件创建一个命名空间,和包含2个容器的pod
[root@master pod2]# cat simple-pod.yaml
apiVersion: v1
kind: Namespace
metadata:
name: sc
---
apiVersion: v1
kind: Pod
metadata:
name: sc-nginx-redis
namespace: sc
spec:
containers:
- name: sc-nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- name: sc-redis
image: redis:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
nodeName: node-2
[root@master pod2]# kubectl apply -f simple-pod.yaml
# 进入sc这个命名空间中sc-nginx-redis这个pod中的容器sc-nginx
[root@master pod2]# kubectl exec -n sc sc-nginx-redis -c sc-nginx -it -- /bin/bash
pod的终止过程
- 用户向apiserver发送删除pod对象的命令
- apiserver中的pod对象信息回随着时间的推移而更新,在宽限期内(默认30s),pod被视为dead
- pod被标记为terminating状态
- kubelet在监控到pod对象转为terminating状态的同时启动pod关闭过程
- 断点控制器监控到pod对象的关闭行为时将其从所有匹配到此断点的service资源的断点列表中移除
- 如果当前pod对象定义了prestop钩子处理器,则在其标记为terminating后即会以同步的方式启动执行
- pod对象中的容器进程收到停止信号
- 宽限期结束后,若pod中还存在仍在运行的进程,那么pod对象会收到立即终止的信号
- kubelet请求apiserver将此pod资源的宽限期设置为0从而完成删除操作,此时pod对于用户已不可见