一、 pod介绍
在kubernetes的世界中,k8s并不直接处理容器,而是使用多个容器共存的理念,这组容器就叫做pod。
pod是k8s中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,其他的资源对象都是用来支撑pod对象功能的,比如,pod控制器就是用来管理pod对象的,service或者imgress资源对象是用来暴露pod引用对象的,persistentvolume资源是用来为pod提供存储等等,简而言之,k8s不会直接处理容器,而是pod,pod才是k8s中可以创建和管理的最小单元,也是基本单元。
二、pod的特点
- 每个pod就像一个独立的逻辑机器,k8s会为每个pod分配一个集群内部唯一的IP地址,所以每个pod都拥有自己的IP地址、主机名、进程等;
- 一个pod可以包含1个多多个容器,1个容器一般被设计成只运行1个进程,1个pod只可能运行在单个节点上,即不可能1个pod跨节点运行,pod的生命周期是短暂的,也就是说pod可能随时被消亡(如节点异常,pod异常等情况);
- 每个pod都有一个特殊的被称为"根容器"的pause容器,也称为info容器,pause容器对应的镜像属于k8s平台的一部分,除了pause容器,每个pod还包含了一个或多个跑业务相关组件的容器;
- 一个pod中的容器共享network命名空间;
- 一个pod里的多个容器共享pod IP,这就意味着1个pod里面的多个容器的进程所占用的端口不能相同,否则在这个pod里面就会产生端口冲突,既然每个pod都有自己的IP和端口空间,那么对不同的pod来说就不可能存在端口冲突;
- 应该就应用程序组织到多个pod中,而每个pod只包含紧密相关的组件或进程;
- 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
# 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
# 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
# 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: 4d32f0fa5e998cbc78194c118e73353731dd1c7b93f6a61b4b3e9e6d6948938ccni.projectcalico.org/podIP: 192.168.69.212/32cni.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 # 容器IDImage: nginx # 镜像Image ID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31 #镜像IDPort: 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 StatusInitialized True Ready True ContainersReady True PodScheduled True
Volumes:default-token-2jswl:Type: Secret (a volume populated by a Secret)SecretName: default-token-2jswlOptional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.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-worker02Normal Pulling 6m14s kubelet, k8s-worker02 Pulling image "nginx"Normal Pulled 5m58s kubelet, k8s-worker02 Successfully pulled image "nginx" in 15.560370431sNormal Created 5m58s kubelet, k8s-worker02 Created container nginxNormal Started 5m58s kubelet, k8s-worker02 Started container nginx
查看pod的yaml文件
kubectl get pod nginx -o yaml
# kubectl get pod nginx -o yaml
apiVersion: v1
kind: Pod
metadata:annotations:cni.projectcalico.org/containerID: 4d32f0fa5e998cbc78194c118e73353731dd1c7b93f6a61b4b3e9e6d6948938ccni.projectcalico.org/podIP: 192.168.69.212/32cni.projectcalico.org/podIPs: 192.168.69.212/32creationTimestamp: "2024-02-22T02:41:11Z"labels:app: nginxmanagedFields:- apiVersion: v1fieldsType: FieldsV1fieldsV1: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-runoperation: Updatetime: "2024-02-22T02:41:11Z"- apiVersion: v1fieldsType: FieldsV1fieldsV1:f:metadata:f:annotations:.: {}f:cni.projectcalico.org/containerID: {}f:cni.projectcalico.org/podIP: {}f:cni.projectcalico.org/podIPs: {}manager: calicooperation: Updatetime: "2024-02-22T02:41:12Z"- apiVersion: v1fieldsType: FieldsV1fieldsV1: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: kubeletoperation: Updatetime: "2024-02-22T02:41:28Z"name: nginxnamespace: defaultresourceVersion: "795586"selfLink: /api/v1/namespaces/default/pods/nginxuid: 814ff88b-a5ec-4bb1-9393-4c2b75807cf6
spec:containers:- image: nginximagePullPolicy: Alwaysname: nginxports:- containerPort: 80protocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: default-token-2jswlreadOnly: truednsPolicy: ClusterFirstenableServiceLinks: truenodeName: k8s-worker02preemptionPolicy: PreemptLowerPrioritypriority: 0restartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}serviceAccount: defaultserviceAccountName: defaultterminationGracePeriodSeconds: 30tolerations:- effect: NoExecutekey: node.kubernetes.io/not-readyoperator: ExiststolerationSeconds: 300- effect: NoExecutekey: node.kubernetes.io/unreachableoperator: ExiststolerationSeconds: 300volumes:- name: default-token-2jswlsecret:defaultMode: 420secretName: default-token-2jswl
status:conditions:- lastProbeTime: nulllastTransitionTime: "2024-02-22T02:41:11Z"status: "True"type: Initialized- lastProbeTime: nulllastTransitionTime: "2024-02-22T02:41:28Z"status: "True"type: Ready- lastProbeTime: nulllastTransitionTime: "2024-02-22T02:41:28Z"status: "True"type: ContainersReady- lastProbeTime: nulllastTransitionTime: "2024-02-22T02:41:11Z"status: "True"type: PodScheduledcontainerStatuses:- containerID: docker://f3e553dbfdb1b77773ee07f35024cdb77b1d32d55c13d10ee4fcb445e25a6b54image: nginx:latestimageID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31lastState: {}name: nginxready: truerestartCount: 0started: truestate:running:startedAt: "2024-02-22T02:41:28Z"hostIP: 192.168.44.155phase: RunningpodIP: 192.168.69.212podIPs:- ip: 192.168.69.212qosClass: BestEffortstartTime: "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
# 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 2m58sNAME 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
# 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: nginxname: nginxnamespace: defaultresourceVersion: "799626"selfLink: /api/v1/namespaces/default/services/nginxuid: fc4a5900-1e80-41dc-838b-79d2fc68e640
spec:clusterIP: 10.98.244.33externalTrafficPolicy: Clusterports:- nodePort: 30005 # 修改一下对外暴露的端口为30005,注意:端口是有范围的,NodePort端口范围默认是30000-32767,可以通过修改`kube-apiserver`的参数来进行调整port: 8088protocol: TCPtargetPort: 80selector:app: nginxsessionAffinity: Nonetype: NodePort
status:loadBalancer: {}
保存后,再次查看service 和 pod
kubectl get pod,svc nginx
# kubectl get pod,svc nginx
NAME READY STATUS RESTARTS AGE
pod/nginx 1/1 Running 1 48mNAME 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