12. Pod 从入门到深入理解(一)
本章讲解知识点
- Pod 的定义和组成
- 静态 Pod
- 使用 Pod 原因与好处
<br>
1. Pod 的定义和组成
1.1 基本概念
Pod 是 Kubernetes 中最小的可部署的单元。Pod 可以包含一个或多个紧密关联的容器,并共享同一个网络和存储空间等资源。Pod 是 Kubernetes 中的一个抽象层,它封装了一个或多个容器,并提供了一个单一的部署单位,即 Pod,使得这些容器能够协同工作。
Pod 的组成包括:
- 容器:Pod 中包含一个或多个容器,每个容器都运行着一个应用程序或服务。同时每个 Pod 都有一个最基本的 Pause 容器。
- 共享存储卷:Pod 中的所有容器可以共享同一个存储卷 Volume,这样它们就可以在运行时共享数据。
- 网络命名空间:每个 Pod 内部容器共享网络命名空间 Network Namespace,这使得 Pod 中的所有容器可以使用同一个 IP 地址和端口空间,从而实现容器间的通信。
- IP地址:每个 Pod 都有自己的 IP 地址,这使得 Pod 之间可以通过该 IP 地址进行通信。
- 生命周期:Pod 有自己的生命周期,从创建到删除。在生命周期中,Pod 可以被创建、更新和删除,以及进行自动伸缩和滚动更新等操作。
需要注意的是,Pod 并不是一个持久的实体,而是一个运行时的实例。当 Pod 中的所有容器终止运行时,Pod 也将被删除。因此,在使用 Pod 时需要考虑容器之间的紧密关联以及 Pod 的生命周期等因素。
1.2 小实验
来创建和部署我们的第一个 Pod
在 Kubernetes 中,可以使用Kubernetes命令行工具(kubectl)来创建和部署 Pod。下面,我们将介绍这种方法。
使用 kubectl 创建和部署 Pod:
1.创建一个 my-first-pod.yaml 文件并填入以下内容,即 Pod 定义文件。
apiVersion: v1 kind: Pod metadata: name: my-first-pod spec: containers: - name: my-first-container image: nginx:latest ports: - containerPort: 80
2.使用 kubectl create
创建 Pod:
kubectl create -f my-first-pod.yaml [root@master mtuser]# kubectl create -f my-first-pod.yaml pod/my-first-pod created
3.这将根据 my-first-pod.yaml 文件中的定义创建一个 Pod,并将其部署到 Kubernetes 集群中。可以使用以下命令查看 Pod。
kubectl get pods [root@master mtuser]# kubectl get pods NAME READY STATUS RESTARTS AGE my-first-pod 1/1 Running 0 40s
4.如果需要更新Pod的定义,如更改镜像版本、端口号,可以编辑 my-first-pod.yaml 文件,并使用以下命令进行更新:
kubectl apply -f my-first-pod.yaml
当然也可以使用 kubectl edit
命令直接编辑 Pod,:wq
保存退出后 Pod 将自动更新。
1.3. 常用参数解释
Kubernetes 中的 Pod 是由一个或多个容器组成的,而 Pod 的定义文件包括许多不同的参数,下面是一些常用的 Pod 定义文件参数及其解释:
- version:版本号,例如 v1。参数必选。
- kind:资源类型,例如 Pod。参数必选。
- metadata:Pod 的元数据。
- metadata.name:Pod 名称。参数必选。如 my-first-pod
- metadata.namespace:Pod 命名空间。默认为 default。
- metadata.labels:用于标记 Pod 的标签,可以用于选择和管理 Pod。
- metadata.annotations:用于注释 Pod 的注释,包含一些额外的元数据信息。
- spec:Pod 中容器的详细定义。
- spec.containers:Pod 中的容器列表。
- spec.containers.name:容器名称。参数必选。如 my-first-container
- spec.containers.image:容器镜像名称。参数必选。如 nginx:latest
- spec.restartPolicy:容器失败后的重启策略,包括 Always(总是重启)、OnFailure(失败后重启)、Never(不重启)等选项。
我们发现,其实一个 Pod 定义只要有必选参数即可,其他参数 Kubernetes 会帮我们自动生成,值为默认即可。
Pod 参数还有很多,我们不急,在学习的过程中会慢慢讲解。
1.4. Pod 定义文件发生的变化
我们输入以下命令来看看 Pod 的信息:
kubectl edit pod my-first-pod
# 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: Pod metadata: creationTimestamp: "2023-02-23T21:57:25Z" name: my-first-pod namespace: default resourceVersion: "220558" selfLink: /api/v1/namespaces/default/pods/my-first-pod uid: 4406f2a6-872a-4e3c-8250-2ed3da0a1882 spec: containers: - image: nginx:latest imagePullPolicy: Always name: my-first-container ports: - containerPort: 80 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-rfwmj readOnly: true dnsPolicy: ClusterFirst enableServiceLinks: true nodeName: node1 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-rfwmj secret: defaultMode: 420 secretName: default-token-rfwmj status: conditions: - lastProbeTime: null lastTransitionTime: "2023-02-23T22:15:38Z" status: "True" type: Initialized - lastProbeTime: null lastTransitionTime: "2023-02-23T22:15:59Z" status: "True" type: Ready - lastProbeTime: null lastTransitionTime: "2023-02-23T22:15:59Z" status: "True" type: ContainersReady - lastProbeTime: null lastTransitionTime: "2023-02-23T21:57:26Z" status: "True" type: PodScheduled containerStatuses: - containerID: docker://7d249e739e8ed9ab9f8fb556cb07c01a4fde8ad93f0ee92243678eb0ac4bdeca image: nginx:latest imageID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31 lastState: {} name: my-first-container ready: true restartCount: 0 state: running: startedAt: "2023-02-23T22:15:59Z" hostIP: 192.168.18.130 phase: Running podIP: 10.244.1.49 qosClass: BestEffort startTime: "2023-02-23T22:15:38Z"
本来我们创建的 Pod 参数很少,运行起来后,Kubernetes 帮助我们填充了不少内容。最重要的三个部分分别为:metadata、spec、status,可以帮助我们获取该 Pod 的不少运行信息,如容器的运行状态、时间等。这些信息可以有效帮助我们定位问题。
我们还有一种方式也可以看到 Pod 创建出来的信息:
输入以下命令:
kubectl describe pod my-first-pod
[root@master mtuser]# kubectl describe pod my-first-pod Name: my-first-pod Namespace: default Priority: 0 Node: node1/192.168.18.130 Start Time: Thu, 23 Feb 2023 17:15:38 -0500 Labels: <none> Annotations: <none> Status: Running IP: 10.244.1.49 Containers: my-first-container: Container ID: docker://7d249e739e8ed9ab9f8fb556cb07c01a4fde8ad93f0ee92243678eb0ac4bdeca Image: nginx:latest Image ID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31 Port: 80/TCP Host Port: 0/TCP State: Running Started: Thu, 23 Feb 2023 17:15:59 -0500 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-rfwmj (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-rfwmj: Type: Secret (a volume populated by a Secret) SecretName: default-token-rfwmj Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 6m43s default-scheduler Successfully assigned default/my-first-pod to node1 Normal Pulling <invalid> kubelet, node1 Pulling image "nginx:latest" Normal Pulled <invalid> kubelet, node1 Successfully pulled image "nginx:latest" Normal Created <invalid> kubelet, node1 Created container my-first-container Normal Started <invalid> kubelet, node1 Started container my-first-container
在 kubectl describe 命令返回的结果中,你可以清楚地看到这个 Pod 的详细信息,比如它的 IP 地址等等。其中,有一个部分值得你特别关注,它就是 Events(事件)。在 Kubernetes 执行的过程中,对 API 对象的所有重要操作,都会被记录在这个对象的 Events 里,并且显示在 kubectl describe 指令返回的结果中。比如,对于这个 Pod,我们可以看到它被创建之后,被调度器调度(Successfully assigned)到了 node1,拉取了指定的镜像(pulling image),然后启动了 Pod 里定义的容器(Started container)。所以,这个部分正是我们将来进行 Debug 的重要依据。如果有异常发生,你一定要第一时间查看这些 Events,往往可以看到非常详细的错误信息。
我们来小结一下刚才使用到的命令:
kubectl create -f my-first-pod.yaml //创建资源 kubectl apply -f my-first-pod.yaml //更新资源 kubectl delete -f my-first-pod.yaml //删除资源 kubectl get pods //查看 Pod kubectl edit pod my-first-pod //编辑 Pod,如果更新了里面的内容,Pod 也会重建更新 kubectl describe pod my-first-pod //描述 Pod 详细信息 kubectl delete pod my-first-pod //删除 Pod
1.5. 一个 Pod 多个容器演示
最开始的例子,我们是一个 Pod 里创建了一个容器,接下来我们试试一个 Pod 里运行多个容器。
apiVersion: v1 kind: Pod metadata: name: my-first-pod spec: containers: - name: my-first-container image: nginx:latest ports: - containerPort: 80 - name: my-second-container image: redis:latest ports: - containerPort: 90
执行命令:
[root@master mtuser]# kubectl delete -f my-first-pod.yaml pod "my-first-pod" deleted [root@master mtuser]# kubectl create -f my-first-pod.yaml pod/my-first-pod created [root@master mtuser]# kubectl get pods NAME READY STATUS RESTARTS AGE my-first-pod 2/2 Running 0 29s
我们成功实现了一个 Pod 里运行两个容器。我们通常将,
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专刊适合于立志转行云计算的小白,有一定的编程、操作系统、计算机网络、数据结构、算法基础。 本专刊同时也适合于面向云计算(Docker + Kubernetes)求职的从业者。 本专刊囊括了云计算、VMWare、Docker、Kubernetes、Containerd等一系列知识点的讲解,并且最后总