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
相关推荐
川石课堂软件测试3 分钟前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
昌sit!6 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
A ?Charis9 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
wclass-zhengge9 小时前
Docker篇(Docker Compose)
运维·docker·容器
茶馆大橘9 小时前
微服务系列五:避免雪崩问题的限流、隔离、熔断措施
java·jmeter·spring cloud·微服务·云原生·架构·sentinel
北漂IT民工_程序员_ZG10 小时前
k8s集群安装(minikube)
云原生·容器·kubernetes
coding侠客10 小时前
揭秘!微服务架构下,Apollo 配置中心凭啥扮演关键角色?
微服务·云原生·架构
梦魇梦狸º13 小时前
腾讯轻量云服务器docker拉取不到镜像的问题:拉取超时
docker·容器·github
南猿北者15 小时前
docker镜像仓库常用命令
运维·docker·容器
2301_8061313616 小时前
Kubernetes的基本构建块和最小可调度单元pod-0
云原生·容器·kubernetes