k8s-pod的介绍及命令行创建pod

一、 pod介绍

在kubernetes的世界中,k8s并不直接处理容器,而是使用多个容器共存的理念,这组容器就叫做pod。

pod是k8s中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,其他的资源对象都是用来支撑pod对象功能的,比如,pod控制器就是用来管理pod对象的,service或者imgress资源对象是用来暴露pod引用对象的,persistentvolume资源是用来为pod提供存储等等,简而言之,k8s不会直接处理容器,而是pod,pod才是k8s中可以创建和管理的最小单元,也是基本单元。

二、pod的特点

  1. 每个pod就像一个独立的逻辑机器,k8s会为每个pod分配一个集群内部唯一的IP地址,所以每个pod都拥有自己的IP地址、主机名、进程等;
  2. 一个pod可以包含1个多多个容器,1个容器一般被设计成只运行1个进程,1个pod只可能运行在单个节点上,即不可能1个pod跨节点运行,pod的生命周期是短暂的,也就是说pod可能随时被消亡(如节点异常,pod异常等情况);
  3. 每个pod都有一个特殊的被称为"根容器"的pause容器,也称为info容器,pause容器对应的镜像属于k8s平台的一部分,除了pause容器,每个pod还包含了一个或多个跑业务相关组件的容器;
  4. 一个pod中的容器共享network命名空间;
  5. 一个pod里的多个容器共享pod IP,这就意味着1个pod里面的多个容器的进程所占用的端口不能相同,否则在这个pod里面就会产生端口冲突,既然每个pod都有自己的IP和端口空间,那么对不同的pod来说就不可能存在端口冲突;
  6. 应该就应用程序组织到多个pod中,而每个pod只包含紧密相关的组件或进程;
  7. pod是k8s扩容,缩容的基本单位,也就是说k8s中扩容缩容是针对pod而言而并非容器。
    pod共享存储实现机制:引入数据卷volume,使用数据卷进行持久化存储。

三、pod背后的根本原理

一个容器一般被设计一个进程,除非进程本身产生子进程,由于不能将多个进程聚集在同一个单独的容器中,所有需要一种更高级的结构容器绑定在一起,并将它们作为一个单元进行管理,这就是pod背后原理。

四、命令行创建pod、查看pod

#注意:kubectl run 在旧版本中创建的是deployment,但在本书的版本中创建的是pod

创建pod

复制代码
kubectl run nginx --image=nginx --labels="app=nginx" --port=80
  • kubectl run nginx 创建一个pod,pod名称为nginx
  • --image=nginx 容器镜像为nginx:latest
  • --labels="app=nginx" 设置一个标签app=nginx
  • --port=80 声明pod的服务端口为80

查看pod

复制代码
kubectl get pod -n default
bash 复制代码
# kubectl get pod -n default
NAME                      READY   STATUS    RESTARTS   AGE
nginx                     1/1     Running   0          98s
  • -n default 指定资源所属的命名空间,默认是default

查看pod运行在哪个节点上

复制代码
kubectl get pod -n default -o wide
bash 复制代码
# kubectl get pod -n default -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP               NODE           NOMINATED NODE   READINESS GATES
nginx                     1/1     Running   0          4m9s    192.168.69.212   k8s-worker02   <none>           <none>

kubectl desc 命令查看pod的详细信息

复制代码
kubectl describe  pod  nginx
bash 复制代码
# kubectl describe  pod  nginx
Name:         nginx				# pod 名称
Namespace:    default			# 所属命名空间
Priority:     0					# 这个参数是优先级
Node:         k8s-worker02/192.168.44.155			# pod所在节点及节点IP地址
Start Time:   Thu, 22 Feb 2024 10:41:11 +0800		# pod启动时间
Labels:       app=nginx						# pod 标签
Annotations:  cni.projectcalico.org/containerID: 4d32f0fa5e998cbc78194c118e73353731dd1c7b93f6a61b4b3e9e6d6948938c
              cni.projectcalico.org/podIP: 192.168.69.212/32
              cni.projectcalico.org/podIPs: 192.168.69.212/32	# Annotations 是注释
Status:       Running			# pod 运行状态
IP:           192.168.69.212	# pod IP地址
IPs:	
  IP:  192.168.69.212
Containers:						# 容器部分,一个pod可以跑多个容器
  nginx:
    Container ID:   docker://f3e553dbfdb1b77773ee07f35024cdb77b1d32d55c13d10ee4fcb445e25a6b54	# 容器ID
    Image:          nginx		# 镜像
    Image ID:       docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31  #镜像ID
    Port:           80/TCP			# pod服务端口
    Host Port:      0/TCP			
    State:          Running			# 容器状态
      Started:      Thu, 22 Feb 2024 10:41:28 +0800		# 容器启动时间
    Ready:          True			# 是否准备就绪
    Restart Count:  0				# 重启次数
    Environment:    <none>			# 环境变量
    Mounts:				# 容器挂载点
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-2jswl (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-2jswl:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-2jswl
    Optional:    false
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:					# pod 启动的事件,在这里可以排查pod异常的原因
  Type    Reason     Age    From                   Message
  ----    ------     ----   ----                   -------
  Normal  Scheduled  6m15s  default-scheduler      Successfully assigned default/nginx to k8s-worker02
  Normal  Pulling    6m14s  kubelet, k8s-worker02  Pulling image "nginx"
  Normal  Pulled     5m58s  kubelet, k8s-worker02  Successfully pulled image "nginx" in 15.560370431s
  Normal  Created    5m58s  kubelet, k8s-worker02  Created container nginx
  Normal  Started    5m58s  kubelet, k8s-worker02  Started container nginx

查看pod的yaml文件

复制代码
kubectl get pod nginx -o yaml
bash 复制代码
# kubectl get pod nginx -o yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    cni.projectcalico.org/containerID: 4d32f0fa5e998cbc78194c118e73353731dd1c7b93f6a61b4b3e9e6d6948938c
    cni.projectcalico.org/podIP: 192.168.69.212/32
    cni.projectcalico.org/podIPs: 192.168.69.212/32
  creationTimestamp: "2024-02-22T02:41:11Z"
  labels:
    app: nginx
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:labels:
          .: {}
          f:app: {}
      f:spec:
        f:containers:
          k:{"name":"nginx"}:
            .: {}
            f:image: {}
            f:imagePullPolicy: {}
            f:name: {}
            f:ports:
              .: {}
              k:{"containerPort":80,"protocol":"TCP"}:
                .: {}
                f:containerPort: {}
                f:protocol: {}
            f:resources: {}
            f:terminationMessagePath: {}
            f:terminationMessagePolicy: {}
        f:dnsPolicy: {}
        f:enableServiceLinks: {}
        f:restartPolicy: {}
        f:schedulerName: {}
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kubectl-run
    operation: Update
    time: "2024-02-22T02:41:11Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:cni.projectcalico.org/containerID: {}
          f:cni.projectcalico.org/podIP: {}
          f:cni.projectcalico.org/podIPs: {}
    manager: calico
    operation: Update
    time: "2024-02-22T02:41:12Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:status:
        f:conditions:
          k:{"type":"ContainersReady"}:
            .: {}
            f:lastProbeTime: {}
            f:lastTransitionTime: {}
            f:status: {}
            f:type: {}
          k:{"type":"Initialized"}:
            .: {}
            f:lastProbeTime: {}
            f:lastTransitionTime: {}
            f:status: {}
            f:type: {}
          k:{"type":"Ready"}:
            .: {}
            f:lastProbeTime: {}
            f:lastTransitionTime: {}
            f:status: {}
            f:type: {}
        f:containerStatuses: {}
        f:hostIP: {}
        f:phase: {}
        f:podIP: {}
        f:podIPs:
          .: {}
          k:{"ip":"192.168.69.212"}:
            .: {}
            f:ip: {}
        f:startTime: {}
    manager: kubelet
    operation: Update
    time: "2024-02-22T02:41:28Z"
  name: nginx
  namespace: default
  resourceVersion: "795586"
  selfLink: /api/v1/namespaces/default/pods/nginx
  uid: 814ff88b-a5ec-4bb1-9393-4c2b75807cf6
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: nginx
    ports:
    - containerPort: 80
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-2jswl
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: k8s-worker02
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: default-token-2jswl
    secret:
      defaultMode: 420
      secretName: default-token-2jswl
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2024-02-22T02:41:11Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2024-02-22T02:41:28Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2024-02-22T02:41:28Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2024-02-22T02:41:11Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://f3e553dbfdb1b77773ee07f35024cdb77b1d32d55c13d10ee4fcb445e25a6b54
    image: nginx:latest
    imageID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
    lastState: {}
    name: nginx
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2024-02-22T02:41:28Z"
  hostIP: 192.168.44.155
  phase: Running
  podIP: 192.168.69.212
  podIPs:
  - ip: 192.168.69.212
  qosClass: BestEffort
  startTime: "2024-02-22T02:41:11Z"

对外暴露服务、测试访问

以上我们创建了一个名为nginx的pod,但是这个pod还不能被外部客户端连接访问,我们还需要做一步就是对外暴露pod,让外部客户端能访问k8s集群的pod服务,所有我们需要创建一个service,并将pod内容器的服务端口映射到节点IP的端口,如下所示:

复制代码
  kubectl expose pod  nginx -n default --port=8088 --target-port=80 --type=NodePort --name=nginx
  • --port=8088 表示集群内节点访问的端口
  • --target=80 表示pod里面容器的应该程序的端口

查看service和pod

复制代码
kubectl get svc,pod nginx
bash 复制代码
# kubectl get svc,pod nginx
NAME            TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/nginx   NodePort   10.98.244.33   <none>        8088:32765/TCP   2m58s

NAME        READY   STATUS    RESTARTS   AGE
pod/nginx   1/1     Running   1          30m
  • 创建了一个nginx service资源对象,并且有一个固定的IP10.98.244.33,并将访问节点端口 32765 的流量转发到 nginx service 的8088端口。service 又将访问8088端口的流量转发到 pod容器内部服务的端口 80
  • 确保防火墙开通了32765 的入方向
  • 所有节点都监听 32765 端口,访问任意节点IP + 32765 都能访问到服务

编辑service

如果需要修改外部访问端口或者需要修改一下刚开定义的service,这时我们可以使用kubectl edit 编辑刚才创建的service,如下:

复制代码
kubectl edit service nginx
bash 复制代码
# kubectl edit service nginx

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2024-02-22T03:08:49Z"
  labels:
    app: nginx
  name: nginx
  namespace: default
  resourceVersion: "799626"
  selfLink: /api/v1/namespaces/default/services/nginx
  uid: fc4a5900-1e80-41dc-838b-79d2fc68e640
spec:
  clusterIP: 10.98.244.33
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 30005			# 修改一下对外暴露的端口为30005,注意:端口是有范围的,NodePort端口范围默认是30000-32767,可以通过修改`kube-apiserver`的参数来进行调整
    port: 8088
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

保存后,再次查看service 和 pod

复制代码
kubectl get pod,svc nginx
bash 复制代码
# kubectl get pod,svc nginx
NAME        READY   STATUS    RESTARTS   AGE
pod/nginx   1/1     Running   1          48m

NAME            TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/nginx   NodePort   10.98.244.33   <none>        8088:30005/TCP   20m

可以看出节点端口已经变成30005了

访问测试:

参考放到最下面,大部分都是借鉴,做了少部分的补充:

复制代码
https://blog.csdn.net/MssGuo/article/details/122894684
相关推荐
我登哥MVP40 分钟前
HDFS硬核拆解-读写Pipeline与Java实战
java·hadoop·hdfs·云原生·云计算
运维老郭13 小时前
【K8s运维实战】Kubernetes临时存储卷实战:emptyDir核心用法与gitRepo弃用迁移指南
运维·云原生·kubernetes
AAA@峥17 小时前
容器数据不丢失:Docker 分层存储 + Volume 共享、备份迁移完整指南
运维·docker·容器
十年磨一剑~18 小时前
docker 为何每次 docker tag才能 docker push
docker·容器·eureka
gs8014020 小时前
记一次多 Agent 架构在单节点 K8s 触发的 PID 耗尽与 Pod 驱逐(Evicted)大摸排
容器·架构·kubernetes
bukeyiwanshui21 小时前
20260701 k8s Metric Server
容器·贪心算法·kubernetes
江湖有缘21 小时前
基于Docker环境部署tillywork开源工作管理工具
docker·容器·开源
鸿儒5171 天前
MR-50国产化GPU docker配置方法
docker·容器·mr
Zhu7581 天前
在k8s集群部署ApacheHadoop单节点单数据副本
云原生·容器·kubernetes