AIOps 一场颠覆传统运维的盛筵
731
2022-10-30
Kubernetes系列7 一 最小编排单位Pod
容器与 kubernetes 的关系就好比是进程与操作系统。对于进程而言,其有更小的粒度线程(linux中进程和线程本质上是一个 task_struct)。一组具有父子关系的 task_struct 共享资源。
所以在 kubernetes 的世界里也模拟了这种关系,容器就好比是每一个 task_struct,而一个逻辑概念 Pod 相当于是这些进程组的集合。
就像进程的所有线程一样,Pod内的所有容器之间共享资源。共享一组Network Namespace、生命相同的Volume。一个 Pod 内的所有容器可以使用 localhost 进行频繁通讯、使用文件直接进行交互。
这里还有一个疑问,那么在一个 Pod 内的这一组容器怎么体现出进程和线的父子关系的呢,按照我们上面所述,容器相当于是线程,那么管理这些线程的“进程” 逻辑概念是什么呢?
在启动一个 Pod 的时候,需要有一个单独的容器来作为这个 “进程” ,叫做 infra 容器。infra 容器和其他应用服务的容器的关系可以变现为如下图所示:
如图所示,在Pod启动时,首先会启动一个名称为 k8s.gcr.io/pause 的 infra 容器,其他的应用程序容器会以 join Network Namespace 的方式与infra容器建立关系。k8s.gcr.io/pause 是一个使用汇编语言编写的镜像,仅仅只占用100到200kb空间。
由于infra容器、容器A、容器B 共享一个 Network Namespace,所以:
infra容器、容器A、容器B 的ip地址一样;容器A、容器B之间可以通过localhost进行通讯。
如果我们在一个Pod内有业务容器启动顺序的需求,例如需要容器A先于B启动,那么我们可以把容器A定义为 Init Container。如果有一组需要优先启动的容器则会按照 Init Container定义的容器顺序启动容器。
我们来看一个demo yaml文件:
apiVersion: v1kind: Podmetadata: name: demo-1spec: initContainers: - image: demo/imageA:v1 name: containerA volumeMounts: - mountPath: root/app name: app-volume initContainers: - image: demo/imageB:v1 name: containerB - mountPath: root/app name: app-volume containers: - image: demo/imageC:v1 name: containerC - mountPath: root/app name: app-volume ports: - containerPort: 8080 hostPort: 80 volumes: - name: app-volume emptyDir: {}
当使用命令 kubelet apply -f demo1.yaml 启动Pod时,首先启动infra容器完成后,会依次启动 containerA、containerB、containerC。
这里也要提一句,并不是说有频繁调用关系的容器就适合部署在一个Pod内,例如一个业务服务和 redis 或者 mysql。
虽然我们从容器开始讲解进入 kubernetes,但是到这里,我们需要非常清晰的树立一个观点,kubernetes 的最小编排单位是 Pod。
apiVersion: v1kind: Pod
metadata: name: pod-demo-nginx namespace: demo labels: k8s-app: nginx version: v1
指定资源的内容,我们先看这两个简单的资源类型定义:restartPolicy:Always 容器异常后一直重启,保存运行;nodeSelector:选择标签 nodeName: node1的Node,在元数据里定义的label被其他资源用来选择;
spec:restartPolicy: Always nodeSelector: nodeName: node1
完整的示例如下:
apiVersion: v1kind: Podmetadata: name: pod-demo-nginx namespace: demo labels: k8s-app: nginx version: v1spec: restartPolicy: Always nodeSelector: nodeName: node1 containers: - name: nginx-1 image: nginx:latest imagePullPolicy: Always resources: requests: cpu: 0.1 memory: 1GB limits: cpu: 0.3 memory: 2GB ports: - containerPort: 80 name: httpd protocol: TCP livenessProbe: httpGet: path: / port: 80 scheme: HTTP initialDelaySeconds: 10 timeoutSeconds: 3 periodSeconds: 5 hostAliases: - ip: "127.0.0.1" hostnames: - "ng.demo" volumeMounts: - name: volume mountPath: /etc/nginx readOnly: True volumes: - name: volume hostPath: path: /opt/nginx
除了以上的定义,大家还要注意一个特殊的NodeName,当Pod被Kubernetes调度成功了,kubernetes会给改Pod的NodeName赋值为这个节点的名称。
这一节我们了解了 Pod 是 kubernetes 中最小的调度单位。知道了Pod 其实就是 kubernetes 通过 infra 容器来实现对其他容器的拓扑结构的虚拟概念。同时一起学习了 Pod 的yaml文件编写过程。
对于 containers 节点,还有许多的属性,例如 Lifecycle 等,我们将在下节结合着 Pod 的生命周期讲解。下一节会带来一个实际的例子来动手实践一个Pod的完整生命周期,以及了解 Pod 更多的应用。
本系列回顾:
Kubernetes系列1 一 容器是什么?
Kubernetes系列2 一 小鲸鱼与船长的历险记
Kubernetes系列3 一 docker隔离与限制的原理
Kubernetes系列4 一 docker镜像
Kubernetes系列5 一 实践课
Kubernetes系列6 一 Kubernetes登场
发表评论
暂时没有评论,来抢沙发吧~