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等一系列知识点的讲解,并且最后总

全部评论

相关推荐

02-14 12:40
门头沟学院 Java
程序员花海:1.面试要求必须Java笔试不一定 2.难度对等秋招 远超于日常实习是因为同一批次且转正很多 竞争压力大 3.第一个加点指标,上线了就把接口性能加上去 使用本地缓存这个不算亮点 只是技术选型,要把为什么采用这个和背后的思考写出来而不是单纯堆叠技术没意义 4.八股要一直看 很容易忘记 5.拼团交易这个老问题 堆积技术 另外建议你把奖项合并到教育背景 没必要拆出来放最后
我的简历长这样
点赞 评论 收藏
分享
bg双非本科,方向是嵌入式。这次秋招一共拿到了&nbsp;8&nbsp;个&nbsp;offer,最高年包&nbsp;40w,中间也有一段在海康的实习经历,还有几次国家级竞赛。写这篇不是想证明什么,只是想把自己走过的这条路,尽量讲清楚一点,给同样背景的人一个参考。一、我一开始也很迷茫刚决定走嵌入式的时候,其实并没有一个特别清晰的规划。网上的信息很零散,有人说一定要懂底层,有人说项目更重要,也有人建议直接转方向。很多时候都是在怀疑:1.自己这种背景到底有没有机会2.现在学的东西到底有没有用3.是不是已经开始晚了这些问题,我当时一个都没答案。二、现在回头看,我主要做对了这几件事第一,方向尽早确定,但不把自己锁死。我比较早就确定了嵌入式这个大方向,但具体做哪一块,是在项目、竞赛和实习中慢慢调整的,而不是一开始就给自己下结论。第二,用项目和竞赛去“证明能力”,而不是堆技术名词。我不会刻意追求学得多全面,而是确保自己参与的每个项目,都能讲清楚:我负责了什么、遇到了什么问题、最后是怎么解决的。第三,尽早接触真实的工程环境。在海康实习的那段时间,对我触动挺大的。我开始意识到,企业更看重的是代码结构、逻辑清晰度,以及你能不能把事情说清楚,而不只是会不会某个知识点。第四,把秋招当成一个需要长期迭代的过程。简历不是一次写完的,面试表现也不是一次就到位的。我会在每次面试后复盘哪些问题没答好,再针对性补。三、我踩过的一些坑现在看也挺典型的:1.一开始在底层细节上纠结太久,投入产出比不高2.做过项目,但前期不会总结,导致面试表达吃亏3.早期有点害怕面试,准备不充分就去投这些弯路走过之后,才慢慢找到节奏。四、给和我背景相似的人一点建议如果你也是双非,准备走嵌入式,我觉得有几件事挺重要的:1.不用等“准备得差不多了”再投2.项目一定要能讲清楚,而不是做完就算3.不要只盯着技术,多关注表达和逻辑很多时候,差的不是能力,而是呈现方式。五、写在最后这篇总结不是标准答案,只是我个人的一次复盘。后面我会陆续把自己在嵌入式学习、竞赛、实习和秋招中的一些真实经验拆开来讲,希望能对后来的人有点帮助。如果你正好也在这条路上,希望你能少走一点弯路。
x_y_z1:蹲个后续
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务