跳转至

kubernets ymal

1 通用部分

  • apiVersion <string>:必选,版本号,例如 v1(必选)
  • kind <string>:资源类型,例如 Pod(必选)
  • metadata <Object>:资源的元数据(必选)
  • spec <Object>:资源的详细定义
  • 示例
apiVersion: v1
kind: Namespace
metadata:
  name: test

2 Pod

  • 常用字段:
  • spec
    • containers:容器相关定义
      • image:镜像
      • imagePullPolicy:镜像拉取策略
      • ports:暴露端口
      • env:设置容器内环境变量
      • volumeMounts:使用挂载的卷
    • restartPolicy:Pod 重启策略
    • hostNetwork:是否使用主机网络,默认是 false
    • affinity:节点的亲和性,用于计算 Pod 调度 k8s 集群中某个 node 上
    • volumes:卷定义,可使用 nfs、hostPath 等方式
  • 示例
apiVersion: v1
kind: Namespace
metadata:
  name: test
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: test
spec:
  containers:
    - name: nginx
      image: nginx
      imagePullPolicy: IfNotPresent       #镜像拉取策略[Never|Always|IfNotPresent]
      ports:
      - containerPort: 80           #容器内端口
        hostPort: 8080              #宿主机端口
        protocol: UDP               #协议类型[TCP|UDP|SCTP](默认TCP)
      - containerPort: 80
        hostPort: 8080
        protocol: TCP
      env:                          #环境变量
      - name: env1
        value: val1
      volumeMounts:
      - name: fs1
        mountPath: /fs1
        readOnly: false
  restartPolicy: Always                   #容器重启策略[Never|Always|OnFailure]
  hostNetwork: false                      #是否使用主机网络[true|false](默认false);如果使用,hostPort不能和containerPort不同
  #nodeName: node1                         #指定k8s节点名称,pod只会调度到此节点上
  #nodeSelector:                           #节点选择器,匹配k8s节点上含test=nginx的节点
  #  test: nginx
  affinity:                               #节点亲和性,pod调度到满足条件的节点上
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:               #必要要满足的条件
        nodeSelectorTerms:
        - matchExpressions:
          - key: test
            operator: In                                            #便签匹配运算符,有In, NotIn, Exists, DoesNotExist
            values:
            - nginx
      preferredDuringSchedulingIgnoredDuringExecution:              #优先满足的条件
      - weight: 1                                                   #权重,范围1-100
        preference:
          matchExpressions:
          - key: label-1
            operator: In
            values:
            - key-1
      - weight: 50
        preference:
          matchExpressions:
          - key: label-2
            operator: In
            values:
            - key-2
  volumes:
  - name: fs1
    hostPath:                             # hostPath方式挂载,此外还有nfs、ceph等等方式
      path: /root/fs1               #主机挂载点路径
      type: DirectoryOrCreate       #可选参数,默认空

2.1 Pod 分配

2.1.1 nodeSelector 节点标签

2.1.1.1 给节点添加标签
  1. 列出你的集群中的节点, 包括这些节点上的标签:

    kubectl get nodes --show-labels
    

    输出类似如下:

    NAME      STATUS    ROLES    AGE     VERSION        LABELS
    worker0   Ready     <none>   1d      v1.13.0        ...,kubernetes.io/hostname=worker0
    worker1   Ready     <none>   1d      v1.13.0        ...,kubernetes.io/hostname=worker1
    worker2   Ready     <none>   1d      v1.13.0        ...,kubernetes.io/hostname=worker2
    
  2. 从你的节点中选择一个,为它添加标签:

    kubectl label nodes <your-node-name> disktype=ssd
    

    <your-node-name> 是你选择的节点的名称。

  3. 验证你选择的节点确实带有 disktype=ssd 标签:

    kubectl get nodes --show-labels
    

    输出类似如下:

    NAME      STATUS    ROLES    AGE     VERSION        LABELS
    worker0   Ready     <none>   1d      v1.13.0        ...,disktype=ssd,kubernetes.io/hostname=worker0
    worker1   Ready     <none>   1d      v1.13.0        ...,kubernetes.io/hostname=worker1
    worker2   Ready     <none>   1d      v1.13.0        ...,kubernetes.io/hostname=worker2
    

    在前面的输出中,你可以看到 worker0 节点有 disktype=ssd 标签。

2.1.1.2 创建一个将被调度到你选择的节点的 Pod

此 Pod 配置文件描述了一个拥有节点选择器 disktype: ssd 的 Pod。这表明该 Pod 将被调度到有 disktype=ssd 标签的节点。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd
  1. 使用该配置文件创建一个 Pod,该 Pod 将被调度到你选择的节点上:

    kubectl create -f https://k8s.io/examples/pods/pod-nginx.yaml
    
  2. 验证 Pod 确实运行在你选择的节点上:

    kubectl get pods --output=wide
    

    输出类似如下:

    NAME     READY     STATUS    RESTARTS   AGE    IP           NODE
    nginx    1/1       Running   0          13s    10.200.0.4   worker0
    

2.1.2 nodeName 节点名称

你也可以通过设置 nodeName 将某个 Pod 调度到特定的节点。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  nodeName: foo-node # 调度 Pod 到特定的节点
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent

使用此配置文件来创建一个 Pod,该 Pod 将只能被调度到 foo-node 节点。

2.1.3 节点亲和性

  • 官方文档 2 种策略:
  • requiredDuringSchedulingIgnoredDuringExecution:pod 必须调度(不匹配则调度失败)
  • preferredDuringSchedulingIgnoredDuringExecution:pod 优先调度(不匹配可以调度其它节点)
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - antarctica-east1
            - antarctica-west1
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: registry.k8s.io/pause:2.0

在这一示例中,所应用的规则如下: - 节点 必须 包含一个键名为 topology.kubernetes.io/zone 的标签, 并且该标签的取值 必须 为 antarctica-east1 或 antarctica-west1。 - 节点 最好 具有一个键名为 another-node-label-key 且取值为 another-node-label-value 的标签。

2.1.4 污点和容忍度

https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/ 节点亲和性 是 Pod 的一种属性,它使 Pod 被吸引到一类特定的节点(这可能出于一种偏好,也可能是硬性要求)。 污点(Taint) 则相反——它使节点能够排斥一类特定的 Pod。

容忍度(Toleration) 是应用于 Pod 上的。容忍度允许调度器调度带有对应污点的 Pod。 容忍度允许调度但并不保证调度:作为其功能的一部分, 调度器也会 评估其他参数

污点和容忍度(Toleration)相互配合,可以用来避免 Pod 被分配到不合适的节点上。 每个节点上都可以应用一个或多个污点,这表示对于那些不能容忍这些污点的 Pod, 是不会被该节点接受的。

2.2 init 容器

Init 容器在应用容器启动前运行完成。

apiVersion: v1
kind: Pod
metadata:
  name: init-demo
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html
  # 这些容器在 Pod 初始化期间运行
  initContainers:
  - name: install
    image: busybox:1.28
    command:
    - wget
    - "-O"
    - "/work-dir/index.html"
    - http://info.cern.ch
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  dnsPolicy: Default
  volumes:
  - name: workdir
    emptyDir: {}

2.3 容器间共享进程命名空间

当启用进程命名空间共享时,容器中的进程对同一 Pod 中的所有其他容器都是可见的。

使用 Pod .spec 中的 shareProcessNamespace 字段可以启用进程命名空间共享。例如:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  shareProcessNamespace: true
  containers:
  - name: nginx
    image: nginx
  - name: shell
    image: busybox:1.28
    securityContext:
      capabilities:
        add:
        - SYS_PTRACE
    stdin: true
    tty: true
  1. 在集群中创建 nginx Pod:

    kubectl apply -f https://k8s.io/examples/pods/share-process-namespace.yaml
    
  2. 获取容器 shell,执行 ps

    kubectl attach -it nginx -c shell
    

    如果没有看到命令提示符,请按 enter 回车键。在容器 shell 中:

    # 在 “shell” 容器中运行以下命令
    ps ax
    

    输出类似于:

    PID   USER     TIME  COMMAND
        1 root      0:00 /pause
        8 root      0:00 nginx: master process nginx -g daemon off;
       14 101       0:00 nginx: worker process
       15 root      0:00 sh
       21 root      0:00 ps ax
    

你可以在其他容器中对进程发出信号。例如,发送 SIGHUP 到 nginx 以重启工作进程。 此操作需要 SYS_PTRACE 权能。

# 在 “shell” 容器中运行以下命令
kill -HUP 8   # 如有必要,更改 “8” 以匹配 nginx 领导进程的 PID
ps ax

输出类似于:

PID   USER     TIME  COMMAND
    1 root      0:00 /pause
    8 root      0:00 nginx: master process nginx -g daemon off;
   15 root      0:00 sh
   22 101       0:00 nginx: worker process
   23 root      0:00 ps ax

甚至可以使用 /proc/$pid/root 链接访问另一个容器的文件系统。

# 在 “shell” 容器中运行以下命令
# 如有必要,更改 “8” 为 Nginx 进程的 PID
head /proc/8/root/etc/nginx/nginx.conf

输出类似于:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;

2.4 生命周期检查

2.5 生命周期钩子

3 Pod控制器

https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/

3.1 Deployment

Deployment 是pod控制器的一种,实际上通常使用控制器来管理Pod,很少直接用Pod
  • 常用字段
  • spec
    • replicas:Pod 副本数
    • selector:标签选择器,用于匹配 template 中定义的 Pod
    • strategy:更新策略(影响镜像修改,扩缩容操作)
    • template:Pod 模板,语法大致和 Pod ymal 语法相同
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 3                         #Pod副本数量
  selector:
    matchLabels:                      #匹配下面容器定义的标签
      app: nginx
  strategy:                           #更新策略
    type: RollingUpdate
    rollingUpdate:                    #滚动更新策略,当type: RollingUpdate时才能用
      maxSurge: 1                 #滚动更新时,最多比期望的副本数多几个pod maxSurge和maxUnavailable不能同时为0,否则冲突,无法滚动更新。可以使用百分比(30%)和数值方式(2)
      maxUnavailable: 1           #滚动更新时,最多比期望的副本数少几个pod
    type: RollingUpdate           #更新策略,[Recreate,RollingUpdate]。Recreate删除pod后再重建;RollingUpdate滚动更新,新老pod可以同时存在
  template:                           #这部分基本与pod中定义相似
    metadata:
      labels:
        app: nginx                #此标签用于上面selector匹配的
    spec:
      containers:
      - image: nginx
        name: nginx

3.2 StatefulSet

4 Volume 卷

4.1 configMap

configMap 卷提供了向 Pod 注入配置数据的方法。 ConfigMap 对象中存储的数据可以被 configMap 类型的卷引用,然后被 Pod 中运行的容器化应用使用。

引用 configMap 对象时,你可以在卷中通过它的名称来引用。 你可以自定义 ConfigMap 中特定条目所要使用的路径。 下面的配置显示了如何将名为 log-config 的 ConfigMap 挂载到名为 configmap-pod 的 Pod 中:

apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: busybox:1.28
      command: ['sh', '-c', 'echo "The app is running!" && tail -f /dev/null']
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: log-config
        items:
          - key: log_level
            path: log_level

log-config ConfigMap 以卷的形式挂载,并且存储在 log_level 条目中的所有内容都被挂载到 Pod 的 /etc/config/log_level 路径下。 请注意,这个路径来源于卷的 mountPath 和 log_level 键对应的 path

说明:

  • 在使用 ConfigMap 之前你首先要创建它。
  • ConfigMap 总是以 readOnly 的模式挂载。
  • 容器以 subPath 卷挂载方式使用 ConfigMap 时,将无法接收 ConfigMap 的更新。
  • 文本数据挂载成文件时采用 UTF-8 字符编码。如果使用其他字符编码形式,可使用 binaryData 字段。

4.2 emptyDir

对于定义了 emptyDir 卷的 Pod,在 Pod 被指派到某节点时此卷会被创建。 就像其名称所表示的那样,emptyDir 卷最初是空的。尽管 Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同,但这些容器都可以读写 emptyDir 卷中相同的文件。 当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会被永久删除。

说明:容器崩溃并会导致 Pod 被从节点上移除,因此容器崩溃期间 emptyDir 卷中的数据是安全的。

emptyDir 的一些用途:

  • 缓存空间,例如基于磁盘的归并排序。
  • 为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。
  • 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。

emptyDir.medium 字段用来控制 emptyDir 卷的存储位置。 默认情况下,emptyDir 卷存储在该节点所使用的介质上; 此处的介质可以是磁盘、SSD 或网络存储,这取决于你的环境。 你可以将 emptyDir.medium 字段设置为 "Memory", 以告诉 Kubernetes 为你挂载 tmpfs(基于 RAM 的文件系统)。 虽然 tmpfs 速度非常快,但是要注意它与磁盘不同, 并且你所写入的所有文件都会计入容器的内存消耗,受容器内存限制约束。

你可以通过为默认介质指定大小限制,来限制 emptyDir 卷的存储容量。

配置示例

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 500Mi

4.3 hostPath

hostPath 卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。

例如,hostPath 的一些用法有:

  • 运行一个需要访问 Docker 内部机制的容器;可使用 hostPath 挂载 /var/lib/docker 路径。
  • 在容器中运行 cAdvisor 时,以 hostPath 方式挂载 /sys
  • 允许 Pod 指定给定的 hostPath 在运行 Pod 之前是否应该存在,是否应该创建以及应该以什么方式存在。

除了必需的 path 属性之外,你可以选择性地为 hostPath 卷指定 type。支持的 type 值如下:

取值 行为
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。
DirectoryOrCreate 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
Directory 在给定路径上必须存在的目录。
FileOrCreate 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。
File 在给定路径上必须存在的文件。
Socket 在给定路径上必须存在的 UNIX 套接字。
CharDevice 在给定路径上必须存在的字符设备。
BlockDevice 在给定路径上必须存在的块设备。
  • 下层主机上创建的文件或目录只能由 root 用户写入。 你需要在 特权容器 中以 root 身份运行进程,或者修改主机上的文件权限以便容器能够写入 hostPath 卷。

4.3.1 hostPath 配置示例

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # 宿主机上目录位置
      path: /data
      # 此字段为可选
      type: Directory

注意:FileOrCreate 模式不会负责创建文件的父目录。 如果欲挂载的文件的父目录不存在,Pod 启动会失败。 为了确保这种模式能够工作,可以尝试把文件和它对应的目录分开挂载,如 FileOrCreate 配置所示。

4.3.2 hostPath FileOrCreate 配置示例

apiVersion: v1
kind: Pod
metadata:
  name: test-webserver
spec:
  containers:
  - name: test-webserver
    image: registry.k8s.io/test-webserver:latest
    volumeMounts:
    - mountPath: /var/local/aaa
      name: mydir
    - mountPath: /var/local/aaa/1.txt
      name: myfile
  volumes:
  - name: mydir
    hostPath:
      # 确保文件所在目录成功创建。
      path: /var/local/aaa
      type: DirectoryOrCreate
  - name: myfile
    hostPath:
      path: /var/local/aaa/1.txt
      type: FileOrCreate

4.4 nfs

nfs 卷能将 NFS (网络文件系统) 挂载到你的 Pod 中。

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /my-nfs-data
      name: test-volume
  volumes:
  - name: test-volume
    nfs:
      server: my-nfs-server.example.com
      path: /my-nfs-volume
      readOnly: true

还需要注意,不能在 Pod spec 中指定 NFS 挂载可选项。 可以选择设置服务端的挂载可选项,或者使用 /etc/nfsmount.conf。 此外,还可以通过允许设置挂载可选项的持久卷挂载 NFS 卷。

如需了解用持久卷挂载 NFS 卷的示例,请参考 NFS 示例

4.5 subPath

4.5.1 使用 subPath

有时,在单个 Pod 中共享卷以供多方使用是很有用的。 volumeMounts.subPath 属性可用于指定所引用的卷内的子路径,而不是其根路径。

下面例子展示了如何配置某包含 LAMP 堆栈(Linux Apache MySQL PHP)的 Pod 使用同一共享卷。 此示例中的 subPath 配置不建议在生产环境中使用。 PHP 应用的代码和相关数据映射到卷的 html 文件夹,MySQL 数据库存储在卷的 mysql 文件夹中:

apiVersion: v1
kind: Pod
metadata:
  name: my-lamp-site
spec:
    containers:
    - name: mysql
      image: mysql
      env:
      - name: MYSQL_ROOT_PASSWORD
        value: "rootpasswd"
      volumeMounts:
      - mountPath: /var/lib/mysql
        name: site-data
        subPath: mysql
    - name: php
      image: php:7.0-apache
      volumeMounts:
      - mountPath: /var/www/html
        name: site-data
        subPath: html
    volumes:
    - name: site-data
      persistentVolumeClaim:
        claimName: my-lamp-site-data

4.5.2 使用带有扩展环境变量的 subPath

特性状态: Kubernetes v1.17 [stable]

使用 subPathExpr 字段可以基于 downward API 环境变量来构造 subPath 目录名。 subPath 和 subPathExpr 属性是互斥的。

在这个示例中,Pod 使用 subPathExpr 来 hostPath 卷 /var/log/pods 中创建目录 pod1。 hostPath 卷采用来自 downwardAPI 的 Pod 名称生成目录名。 宿主机目录 /var/log/pods/pod1 被挂载到容器的 /logs 中。

apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: container1
    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
    image: busybox:1.28
    command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
    volumeMounts:
    - name: workdir1
      mountPath: /logs
      # 包裹变量名的是小括号,而不是大括号
      subPathExpr: $(POD_NAME)
  restartPolicy: Never
  volumes:
  - name: workdir1
    hostPath:
      path: /var/log/pods

4.6 CSI

容器存储接口 (CSI) 为容器编排系统(如 Kubernetes)定义标准接口,以将任意存储系统暴露给它们的容器工作负载。

更多详情请阅读 CSI 设计方案

4.7 持久卷 PV

https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/

4.8 存储类 StorageClass

https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/

5 Service 网络

https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/ Kubernetes 中 Service 是 将运行在一个或一组 Pod上的网络应用程序公开为网络服务的方法。