一、前言

       Pod的原意是豌豆荚的意思,一个豆荚里面包含了很多豆子。在K8S中,Pod也是类似的意思,只不过这里的豆子就是容器。在K8S初级入门系列之一-概述中,我们对Pod有个初步的了解。

1、Pod是K8S编排和调度的最小基础单元。

        了解容器的同学会知道,容器之间通过隔离技术(namespace+cgroup+chroot),实现了应用间的隔离。那么K8S为何不直接使用容器进行调度,而非得再引入Pod的概念,使得模型更加复杂呢?现在的复杂系统有着成百上千的服务,服务与服务之间的关系,从运行环境看,需要做资源的隔离,但是从业务逻辑看,他们又存在亲和性。

       比如下面的系统中,字数统计是应用服务,实现业务功能,Nginx服务负责应用服务的反向代理以及负载均衡,日志采集服务收集应用服务的日志并进行上报,这三个服务必须部署运行在一起,才能对外提供完整的功能。同时为了系统的可靠性,数据库MySql服务需要和应用服务分开部署。

     这个例子中,如果用容器实现,就需要将应用服务,Ngnix服务,日志采集服务放到一个容器中,才能实现统一部署。这种方式不是说不可以,但是违背了容器的设计理念,即一个进程跑一个容器。可以看到,Pod即有利于进程资源的隔离,又能独立打包部署和维护。

      通过Pod就可以把具备亲和性的服务包裹一起,而互斥性的服务部署在不同Pod中,K8S通过对Pod的调度和编排,解决了上述容器无法实现的问题。

  • Pod是K8S中最核心,最基础的概念

K8S的其他组件和概念,基本上都是直接或者间接围绕Pod发展的。如下图所示:

本章节我们先了解Pod的一些基本概念和操作,关于Pod高级特性我们放到后面章节。 

 二、YAML语言

     在了解Pod前,我们先看下YAML语言。在K8S的世界里,所有的对象都可以采用了YAML语言描述,YAML语言类似于JSON,但是比JSON更加的清晰紧促,首先做个对比:

JSON的描述:

{ 
   "students":
      {
          "boy":20,
          "girl":22      
       }
}

YMAL的描述

Students:
  boy:  20
  girl: 22

可以看到,YAML是通过缩减和空白表示层次间的关系。YAML语言需要注意以下几点:

  • 对象与值之间用":"隔开,冒号后面一定要带上空格。
  • 数组或者列表采用"-"开头,横杠后面一定要带上空格。
  • 在一个文件中可以有多个YAML描述对象,使用"---"分割。
  • 使用"#"描写注释

具体的语法可以参见YAML官网

三、Pod的描述

      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,顾名思义,里面可以定义多个容器,容器重要的属性如下:

  • name,容器的名称。
  • image,镜像的名称。
  • env,环境变量,可以配置运行时的环境变量列表。
  • command,容器启动时,执行的指令。
  • args,command启动的入参。
  • ports,容器需要暴露的端口号列表。

Pod对象的属性还有很多,在后续的介绍逐步了解。

四、Pod的操作

     kubectl是K8S的命令行工具(CLI),kubectl 提供了大量的命令,方便管理 Kubernetes 集群中的各种功能,下面我们使用kubectl操作Pod。

1、Pod的创建

使用kubectl apply -f <pod file>指令完成上述Pod的创建。

[root@k8s-master yaml]# kubectl apply -f busybox-pod.yaml 
pod/busybox-pod created

      注意:使用kubectl create也可以创建Pod对象,create是命令式的,而apply是声明式的,其创建逻辑是,不存在则创建,存在则比较差异,进行更新,一般推荐apply。

2、Pod的查看

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   <none>           <none>

该Pod运行在k8s-node1节点上,其ip为10.244.36.75。

通过 kubectl describe pod <podname>可以查看具体某个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:          <none>
    Host Port:     <none>
    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:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
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 <podname>指令查看Pod的日志

[root@k8s-master yaml]# kubectl logs busybox-pod

3、进入Pod

Pod运行期间,可以通过命令kubectl exec -it <podname> sh进入到Pod内部,执行相关命令。

[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 <podname> -c <containername> sh进入到某个容器内部

[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里所有的容器网络是共享的。

4、Pod的删除

使用kubectl delete pod <podname>命令删除一个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初级入门系列之十二-计算资源管理

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐