Pod的原意是豌豆荚的意思,一个豆荚里面包含了很多豆子。在K8S中,Pod也是类似的意思,只不过这里的豆子就是容器。在K8S初级入门系列之一-概述中,我们对Pod有个初步的了解。
1、Pod是K8S编排和调度的最小基础单元。
了解容器的同学会知道,容器之间通过隔离技术(namespace+cgroup+chroot),实现了应用间的隔离。那么K8S为何不直接使用容器进行调度,而非得再引入Pod的概念,使得模型更加复杂呢?现在的复杂系统有着成百上千的服务,服务与服务之间的关系,从运行环境看,需要做资源的隔离,但是从业务逻辑看,他们又存在亲和性。
比如下面的系统中,字数统计是应用服务,实现业务功能,Nginx服务负责应用服务的反向代理以及负载均衡,日志采集服务收集应用服务的日志并进行上报,这三个服务必须部署运行在一起,才能对外提供完整的功能。同时为了系统的可靠性,数据库MySql服务需要和应用服务分开部署。
这个例子中,如果用容器实现,就需要将应用服务,Ngnix服务,日志采集服务放到一个容器中,才能实现统一部署。这种方式不是说不可以,但是违背了容器的设计理念,即一个进程跑一个容器。可以看到,Pod即有利于进程资源的隔离,又能独立打包部署和维护。
通过Pod就可以把具备亲和性的服务包裹一起,而互斥性的服务部署在不同Pod中,K8S通过对Pod的调度和编排,解决了上述容器无法实现的问题。
K8S的其他组件和概念,基本上都是直接或者间接围绕Pod发展的。如下图所示:
本章节我们先了解Pod的一些基本概念和操作,关于Pod高级特性我们放到后面章节。
在了解Pod前,我们先看下YAML语言。在K8S的世界里,所有的对象都可以采用了YAML语言描述,YAML语言类似于JSON,但是比JSON更加的清晰紧促,首先做个对比:
JSON的描述:
{
"students":
{
"boy":20,
"girl":22
}
}
YMAL的描述
Students:
boy: 20
girl: 22
可以看到,YAML是通过缩减和空白表示层次间的关系。YAML语言需要注意以下几点:
具体的语法可以参见YAML官网
K8S采用YAML语言,声明式的描述Pod对象。我们先看下较简单的Pod对象示例。
apiVersion: v1
kind: Pod
metadata:
name: busybox-pod
labels:
app: bash
spec:
containers:
- name: busybox
image: busybox
env:
- name: type
value: prod
- name: log
value: debug
command:
- "/bin/sh"
- "-c"
- "sleep 3000"
args:
- "$(type), $(log)"
Pod对象有apiVersion,kind,metadata,spec四部分组成。apiVersion描述版本,kind描述类型,对于Pod来说,固定为v1和Pod。
metadata描述pod的元数据,一般有name,以及labels。name表示该Pod的名称,labels是Pod的标签,可以有多个,表示Pod的"归类",这个属性很重要,后续的Pod的选择都是依赖标签完成。
spec是对Pod详细定义,本篇我们重点了解containers,顾名思义,里面可以定义多个容器,容器重要的属性如下:
Pod对象的属性还有很多,在后续的介绍逐步了解。
kubectl是K8S的命令行工具(CLI),kubectl 提供了大量的命令,方便管理 Kubernetes 集群中的各种功能,下面我们使用kubectl操作Pod。
使用kubectl apply -f
[root@k8s-master yaml]# kubectl apply -f busybox-pod.yaml
pod/busybox-pod created
注意:使用kubectl create也可以创建Pod对象,create是命令式的,而apply是声明式的,其创建逻辑是,不存在则创建,存在则比较差异,进行更新,一般推荐apply。
pod创建完成后,可以使用kubectl get pod 指令查看所有pod的运行情况。
[root@k8s-master yaml]# kubectl get pod
NAME READY STATUS RESTARTS AGE
busybox-pod 1/1 Running 0 31m
pod的name为我们定义的busybox,状态status为Running。也可以加上"-o wide"看出更多的信息
[root@k8s-master yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox-pod 1/1 Running 0 41m 10.244.36.75 k8s-node1
该Pod运行在k8s-node1节点上,其ip为10.244.36.75。
通过 kubectl describe pod
[root@k8s-master yaml]# kubectl describe pod busybox-pod
Name: busybox-pod
Namespace: default
Priority: 0
Node: k8s-node1/10.0.0.4
Start Time: Sun, 13 Nov 2022 21:43:20 +0800
Labels: app=bash
Annotations: cni.projectcalico.org/containerID: 30d0f991395befa857f6c2814f625f66e008c308564941285c7cd434a5a3ab18
cni.projectcalico.org/podIP: 10.244.36.68/32
cni.projectcalico.org/podIPs: 10.244.36.68/32
Status: Running
IP: 10.244.36.75
IPs:
IP: 10.244.36.75
Containers:
busybox:
Container ID: docker://8b28fddf7104e31279f9dc1773630ee5cf4aef2a1d8311abe9dd0224ac2e0567
Image: busybox
Image ID: docker-pullable://busybox@sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Port:
Host Port:
Command:
/bin/sh
-c
sleep 3000
Args:
$(type), $(log)
State: Running
Started: Sun, 13 Nov 2022 22:33:54 +0800
Last State: Terminated
Reason: Completed
Exit Code: 0
Started: Sun, 13 Nov 2022 21:43:37 +0800
Finished: Sun, 13 Nov 2022 22:33:37 +0800
Ready: True
Restart Count: 1
Environment:
type: prod
log: debug
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-d5mwc (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-d5mwc:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional:
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 58m default-scheduler Successfully assigned default/busybox-pod to k8s-node1
Normal Pulled 58m kubelet Successfully pulled image "busybox" in 16.819473827s
Normal Pulling 8m35s (x2 over 58m) kubelet Pulling image "busybox"
Normal Created 8m19s (x2 over 58m) kubelet Created container busybox
Normal Started 8m19s (x2 over 58m) kubelet Started container busybox
Normal Pulled 8m19s kubelet Successfully pulled image "busybox" in 15.486748688s
详情中包括了pod的信息,container信息,以及events事件信息。特别说明的是,如果pod启动不成功,可以从event事件查看过程。
使用kubectl logs
[root@k8s-master yaml]# kubectl logs busybox-pod
Pod运行期间,可以通过命令kubectl exec -it
[root@k8s-master ~]# kubectl exec -it busybox-pod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # ifconfig
eth0 Link encap:Ethernet HWaddr D2:2C:E7:0F:4B:48
inet addr:10.244.36.75 Bcast:0.0.0.0 Mask:255.255.255.255
UP BROADCAST RUNNING MULTICAST MTU:1480 Metric:1
RX packets:5 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:446 (446.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
进入pod的环境后,执行ifconfig看下ip信息,该pod的ip与上面详情中显示的一致。
也可以使用kubectl exec -it
[root@k8s-master ~]# kubectl exec -it busybox-pod -c busybox sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # ifconfig
eth0 Link encap:Ethernet HWaddr D2:2C:E7:0F:4B:48
inet addr:10.244.36.75 Bcast:0.0.0.0 Mask:255.255.255.255
UP BROADCAST RUNNING MULTICAST MTU:1480 Metric:1
RX packets:5 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:446 (446.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
执行ifconfig后看到到容器的ip和pod的ip是一致的。这个也就是我们后续要讲的pod里所有的容器网络是共享的。
使用kubectl delete pod
[root@k8s-master ~]# kubectl delete pod busybox-pod
pod "busybox-pod" deleted
[root@k8s-master ~]# kubectl get pod
No resources found in default namespace.
在查询列表为空,表示该pod已经删除
Pod是K8S最核心的概念,引入Pod的目的是为了解决存在亲和性和互斥性复杂关系服务的调度和编排问题。
Pod采用YAML声明式的对象描述,主要包括apiVersion,kind,metadata,spec四部分,其中spec中申明该Pod容器列表。
采用kubectl命令行工具,演示了对于Pod的创建,查看,修改,删除等基本操作。
K8S初级入门系列之一-概述
K8S初级入门系列之二-集群搭建
K8S初级入门系列之三-Pod的基本概念和操作
K8S初级入门系列之四-Namespace/ConfigMap/Secret
K8S初级入门系列之五-Pod的高级特性
K8S初级入门系列之六-控制器(RC/RS/Deployment)
K8S初级入门系列之七-控制器(Job/CronJob/Daemonset)
K8S初级入门系列之八-网络
K8S初级入门系列之九-共享存储
K8S初级入门系列之十-控制器(StatefulSet)
K8S初级入门系列之十一-安全
K8S初级入门系列之十二-计算资源管理