Contents

Pod、ReplicaSet 和 Deployment

文档:Pod | Kubernetes

Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。它是一个或多个容器的组合。这些容器共享存储、网络和命名空间,以及如何运行的规范。其它的资源对象都是用来支撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者 Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod 提供存储等等,K8S 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成。基本的好处有:

  1. 方便部署、扩展和收缩、方便调度等

  2. Pod中的容器共享数据和网络空间,统一的资源管理与分配

在Pod中,所有容器都被同一安排和调度,并运行在共享的上下文中。对于具体应用而言,Pod是它们的逻辑主机,Pod包含业务相关的多个应用容器。

https://raw.githubusercontent.com/xuliangTang/picbeds/main/typora/image-20221206200429843.png

每一个 Pod 都有一个特殊的被称为 “根容器” 的 Pause 容器。Pause 容器对应的镜像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod 还包含一个或多个紧密相关的用户业务容器。Pause 容器的作用:

  • 扮演 Pid=1 的,回收僵尸进程
  • 基于 Linux 的 namespace 的共享

https://raw.githubusercontent.com/xuliangTang/picbeds/main/typora/370d5cae852e417cb610697eb4eb4a31.jpeg

Pod 基本使用

Pod 通常不是直接创建的,而是使用工作负载资源创建的

创建

apiVersion: v1
kind: Pod
metadata:
  name: myngx
spec:
  containers:
  - name: ngx
    image: "nginx:1.18-alpine"

展示详细信息

$ kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE    NOMINATED NODE   READINESS GATES
myngx   1/1     Running   0          13m   10.244.3.7   lain2   <none>           <none>

ReplicaSet

ReplicaSet 是为了保持维护的期待 Pod 副本数量与现时 Pod 副本数量一致。如在由于 Pod 异常退出导致期待的副本数量不足时,会自动创建新的 Pod 保证到与期望的 Pod 副本数量一致

使用 Deployment

Deployment 运行一组相同的 Pod(副本水平扩展)、滚动更新。通过副本集管理和创建POD。我们往往不会直接在集群中使用 ReplicaSet 部署一个新的微服务,一方面是因为 ReplicaSet 的功能其实不够强大,一些常见的更新、扩容和缩容运维操作都不支持,Deployment 的引入就是为了就是为了支持这些复杂的操作

https://raw.githubusercontent.com/xuliangTang/picbeds/main/picgo/202212201923111.png

挂载

挂载 hostPath 主机目录卷实例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myngx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: ngx
        image: "nginx:1.18-alpine"
        volumeMounts:  # 声明容器中的挂载位置
        - name: mydata
          mountPath: /data
      - name: alpine  # 测试多容器
        command: ["sh","-c","echo this is alpine && sleep 3600"]
        image: "alpine:3.12"
      volumes:
      - name: mydata
        hostPath:
          path: /home/txl/yaml/data	 # 声明主机节点目录 
          type: Directory  # 指定type

hostPath 支持的 type 值如下:

https://raw.githubusercontent.com/xuliangTang/picbeds/main/typora/202212151848317.png

共享文件夹

同一个 pod 内的容器都能读写 EmptyDir 中的文件。常用于临时空间、多容器共享,如日志或者tmp文件需要的临时目录

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myngx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: ngx
          image: nginx:1.18-alpine
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: sharedata
              mountPath: /data
        - name: alpine
          image: alpine:3.12
          imagePullPolicy: IfNotPresent
          command: ["sh","-c","echo this is alpine && sleep 36000"]
          volumeMounts:
            - name: sharedata
              mountPath: /data
      volumes:
        - name:  sharedata
          emptyDir: {}

Init 容器

文档:Init 容器 | Kubernetes

Init 容器是一种特殊容器,在 Pod 内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。

Init 容器与普通的容器非常像,除了如下两点:

  • 它们总是运行到完成。
  • 每个都必须在下一个启动之前成功完成。

如果 Pod 的 Init 容器失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止。 然而,如果 Pod 对应的 restartPolicy 值为 “Never”,Kubernetes 不会重新启动 Pod。

原理

在 Pod 启动过程中,每个 Init 容器会在网络和数据卷初始化之后按顺序启动。 依据 Init 容器在 Pod spec 配置中的出现顺序依次运行。由于 Pod 可能各种原因多次重启,所以 Init 容器中的操作,须具备幂等性。

应用场景

  • 环境检查:例如确保应用容器依赖的服务启动后再启动应用容器
  • 初始化配置:例如给应用容器准备配置文件

基本配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myngx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      initContainers:
        - name: init-mydb
          image: alpine:3.12
          command: ['sh', '-c', 'echo wait for db && sleep 35 && echo done'] # 模拟等待35s
      containers:
        - name: ngx
          image: nginx:1.18-alpine
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: sharedata
              mountPath: /data
        - name: alpine
          image: alpine:3.12
          imagePullPolicy: IfNotPresent
          command: ["sh","-c","echo this is alpine && sleep 36000"]
          volumeMounts:
            - name: sharedata
              mountPath: /data
      volumes:
        - name:  sharedata
          emptyDir: {}

查看 init 容器状态

$ kubectl get pod
NAME                    READY   STATUS     RESTARTS   AGE
myngx-89dd8586b-k59pl   0/2     Init:0/1   0          8s
状态含义
Init:N/MPod 包含 M 个 Init 容器,其中 N 个已经运行完成。
Init:ErrorInit 容器已执行失败。
Init:CrashLoopBackOffInit 容器执行总是失败。
PendingPod 还没有开始执行 Init 容器。
PodInitializing or RunningPod 已经完成执行 Init 容器。