kubernetes文档知识点个人总结

Updated on with 0 views and 0 comments

只是整理知识点,所有内容来自 http://docs.kubernetes.org.cn/251.html,如有侵权请发送邮件通知删除

架构

图片.png

K8s 主要组件

etcd: 保存集群状态
apiserver: 所有资源操作入口,认证授权,访问控制,API注册,服务发现
controller-manager: 维护集群状态,故障检测,自动扩展,滚动更新
scheduler: 资源调度
kubelet: 维护容器的生命周期,CVI和CNI管理
cri: 镜像管理和pod运行
kube-proxy: 为Service提供cluster服务发现和负载均衡

K8s addons

kube-dns: 集群dns服务,多用cni
IngressController: 外网入口
Heapster: 资源监控
Dashboard: GUI
Federation: 跨区用集群
Fluentd-elasticsearch: 日志采集存储查询

图片.png

分层架构

图片.png

  • 核心层:Kubernetes 最核心的功能,对外提供 API 构建高层的应用,对内提供插件式应用执行环境
  • 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS 解析等)
  • 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态 Provision 等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy 等)
  • 接口层:kubectl 命令行工具、客户端 SDK 以及集群联邦
  • 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
    • Kubernetes 外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS 应用、ChatOps 等
    • Kubernetes 内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

基础概念

Pod: K8S 集群中 运行部署应用或服务的最小单元,支持很多容器。多个容器在一个 Pod 中共享网络地址和文件系统,可以通过进程间通信和文件共享方式组合完成服务。

Pod:负责不同场景的应用服务:Long-Running,Batch,Node-daemon,Stateful application,对应控制器为 Deployment,Job,DaemonSet 和 PetSet

Replication Controller(RC): 复制控制器,CURD POD 的一个 API 对象

Replication Set(RS): 新的 RC

Deployment: 部署 表述用户对 K8S 一次更新操作:创建新服务,更新服务,滚动升级,实际操作是创建 RS,然后使用 RS 渐进创建新的 POD 删除老的 POD 直到达到 命令行参数配置的指标

Service: 服务,RC,RS 和 Deployment 保证 POD 数量,如果通过 ip 端口方式访问 POD,可能你在访问时,这个 POD 被删除迁移到另一个节点上就会出现错误,客户端访问需要的服务就是 Service 对象,每个 Service 对应一个集群内部有效的虚拟 IP,集群内通过虚拟 IP 访问服务。

Job: 任务,控制 Batch 任务的 API 对象,这种任务通常是有头有尾,Job 管理的 Pod 根据用户设置完成任务后退出

  • .spec.completions: 指定 job 需要成功运行 Pods 的次数。默认值: 1
  • .spec.parallelism: 指定 job 在任一时刻应该并发运行 Pods 的数量。默认值: 1
  • .spec.activeDeadlineSeconds: 指定 job 可运行的时间期限,超过时间还未结束,系统将会尝试进行终止。
  • .spec.backoffLimit: 指定 job 失败后进行重试的次数。默认是 6 次,每次失败后重试会有延迟时间,该时间是指数级增长,最长时间是 6min。

DaemonSet: 后台支撑服务集合,长期伺服型服务,只有开始然后等用户手动结束,要保证各每个节点都以一个此类型的服务在运行

PetSet: 有状态服务集合,比如 DB

Federation: 集群联邦 跨区主机,跨云主机分布式集群

Volume: 存储卷,生命周期和作用范围是一个 POD

PV: Persistent Volume,PV 持久存储卷,Persistent Volume Claim PVC 持久卷声明,PV 提供资源,PVC 和 POD 使用 PV

Node: 节点 Mesos 和 Slave,Master 和 Node

Secret: 密钥对象,保存和传递密码认证凭证 ssl 证书等

Namespace: 命名空间,虚拟隔离

RBAC: 用户角色权限

组件

Master

kube-apiserver

kube-controller-manager

kube-scheduler

Node

kubelet

kube-proxy

对象

Kubernetes 对象是持久实体类,用这些实体类来表示集群的状态,比如

  • 容器化应用正在运行在哪些节点上
  • 应用可用资源
  • 应用运行策略,升级策略,容错策略

对象的规范和状态

每个 Kubernetes 对象包含两个嵌套字段用于管理 Object 的配置:Object Spec 和 Object Status

Sepc 表示对象所需的状态,希望对象具有的特性,Status 描述对象的实际状态由 K8S 提供和更新

Demo:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

Object.kind = Deployment 部署类型的对象

Object.metadata.name = nginx-deployment 名称

Object.spec.replicas = 三个应用实例

......

使用 kubectl create 命令创建这个 描述对象

kubectl create -f docs/user-guide/nginx-deployment.yaml --record

Name

Kubernetes REST API 中的所有对象都用 Name 和 UID 来明确标识

Name 在一个对象中同一时间只能拥有单个 Name,如果对象被删除,也可以使用相同 Name 创建新的对象,Name 用于在资源引用 URL 中的对象,例如 /api/v1/pods/some-name。通常情况,Kubernetes 资源的 Name 能有最长到 253 个字符(包括数字字符、-.),但某些资源可能有更具体的限制条件,具体情况可以参考:标识符设计文档

Namespaces

namespace 将一个集群提供不同的分组

# 创建一个namespace
kubectl create namespace spaceName 
# 通过配置文件
apiVersion: v1
kind: Namespace
metadata:
  name: new-namespace

kubectl create -f config.yml  
kubectl delete namespaces new-namespace :删除一个命名空间,删除时会删除所有属于该命名空间的资源
default 和 kube-system 命名空间无法删除
kubectl get namespaces 查看命名空间
临时设置Request的Namespace: 
kubectl --namespace= run nginx --image=nginx
kubectl --namespace= get pods
# 永久保存命名空间
 kubectl config set-context $(kubectl config current-context) --namespace=<insert-namespace-name-here>

大多数 Kubernetes 资源(例如 pod、services、replication controllers 或其他)都在某些 Namespace 中,但 Namespace 资源本身并不在 Namespace 中。而低级别资源(如 Node 和 persistentVolumes)不在任何 Namespace 中。Events 是一个例外:它们可能有也可能没有 Namespace,具体取决于 Events 的对象。

Namespace 配额

通过 ResourceQuota 对象配置 Namespace 配额

# 创建一个命名空间
kubectl create namespace quota-pod-example

# ResourceQuota对象描述yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: pod-demo
spec:
  hard:
    pods: "2"

# 通过yaml在quota-pod-example namespace下创建一个 ResourceQuota 对象
kubectl create -f quota-pod.yaml --namespace=quota-pod-example

# 查看 resourcequota 对象的详细信息
kubectl get resourcequota pod-demo --namespace=quota-pod-example --output=yaml

# 状态 spec 期望 status 实际值由controller管理更新,未使用pods数量2个,已使用pods数量0个
spec:
  hard:
    pods: "2"
status:
  hard:
    pods: "2"
  used:
    pods: "0"

# Deployment 对象,一次部署任务,期望创建3个pod
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: pod-quota-demo
spec:
  replicas: 3
  template:
    metadata:
      labels:
        purpose: quota-demo
    spec:
      containers:
      - name: pod-quota-demo
        image: nginx

# 在 quota-pod-example namespace 下 使用 deployment yaml 创建一个部署任务
kubectl create -f quota-pod-deployment.yaml --namespace=quota-pod-example

# 查看Deployment对象信息
kubectl get deployment pod-quota-demo --namespace=quota-pod-example --output=yaml



# 期望时3个,但是因为ResourceQuota对Namespace做出了限制,所以只有两个Pod
spec:
  ...
  replicas: 3
...
status:
  availableReplicas: 2
...
lastUpdateTime: 2017-07-07T20:57:05Z
    message: 'unable to create pods: pods "pod-quota-demo-1650323038-" is forbidden:
      exceeded quota: pod-demo, requested: pods=1, used: pods=2, limited: pods=2'

内存和 CUP 请求 限 额

对象类型为 LimitRange

apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
spec:
  limits:
  # 默认内存限额为 512M
  - default:
      memory: 512Mi
 # 最大内存限额为 1G
    max:
      memory: 1Gi
 # 最小内存限额为 500M
    min:
      memory: 500Mi
  # 默认请求限额为 256M
    defaultRequest:
      memory: 256Mi
    type: Container

应用最小和最大内存限制

LimitRange 在 namespace 中施加的最小和最大内存限制只有在创建和更新 Pod 时才会被应用。改变 LimitRange 不会对之前创建的 Pod 造成影响。

最小和最大内存限制的动因

作为一个集群管理员,您可能希望为 Pod 能够使用的内存数量施加限制。例如:

  • 集群中每个节点拥有 2 GB 内存。您不希望任何 Pod 请求超过 2 GB 的内存,因为集群中没有节点能支持这个请求。
  • 集群被生产部门和开发部门共享。 您希望生产负载最多使用 8 GB 的内存而将开发负载限制为 512 MB。这种情况下,您可以为生产环境和开发环境创建单独的 namespace,并对每个 namespace 应用内存限制。

内存和 CPU 请求配额

request: 容器使用的最小资源需求, 作为容器调度时资源分配的判断依赖。
limit: 容器能使用资源的最大值

request 能保证 pod 有足够的资源来运行, 而 limit 则是防止某个 pod 无限制的使用资源, 导致其他 pod 崩溃。 两者的关系必须满足:

0 <= request <= limit
apiVersion: v1
// ResourceQuoa对象
kind: ResourceQuota
metadata:
  name: mem-cpu-demo
spec:
  hard:
   // 所有容器CPU请求总额 不超过1G
    requests.cpu: "1"
   // 所有容器内存请求总额 不超过1G
    requests.memory: 1Gi
   // 所有容器CPU请求限额总额不能超过2G
    limits.cpu: "2"
   // 所有容器内存请求限额总额不能超过2G
    limits.memory: 2Gi
apiVersion: v1
// Pod对象
kind: Pod
metadata:
  name: quota-mem-cpu-demo
spec:
  containers:
  - name: quota-mem-cpu-demo-ctr
    image: nginx
    resources:
      limits:
        //内存总额 800MB
        memory: "800Mi"
        // CPU总额 800MB
        cpu: "800m" 
      requests:
        // 内存请求限额总额600MB
        memory: "600Mi"
        // CPU请求限额总额
        cpu: "400m"
apiVersion: v1
 // 第二个POD
kind: Pod
metadata:
  name: quota-mem-cpu-demo-2
spec:
  containers:
  - name: quota-mem-cpu-demo-2-ctr
    image: redis
    resources:
      limits:
        memory: "1Gi"
        cpu: "800m"  
      requests:
        memory: "700Mi"
        cpu: "400m"

当创建第二个 POD 时 发现当前 Namespace 配额的内存和 CPU 都不够用了,抛出了异常

Error from server (Forbidden): error when creating "docs/tasks/administer-cluster/quota-mem-cpu-pod-2.yaml":
pods "quota-mem-cpu-demo-2" is forbidden: exceeded quota: mem-cpu-demo,
requested: requests.memory=700Mi,used: requests.memory=600Mi, limited: requests.memory=1Gi

Label 和 Selectors

Labels 就是 键值对集合 筛选对象用
单个对象中 Label 唯一,但多个对象中 Label 不唯一

List & Watch

LIST 和 WATCH 操作可以指定标签选择器来过滤使用查询参数返回的对象集。

# 根据 environment 和environmentde值筛选POD
kubectl get pods -l environment=production,tier=frontend
kubectl get pods -l 'environment in (production),tier in (frontend)'
kubectl get pods -l 'environment in (production, qa)'
kubectl get pods -l 'environment,environment notin (frontend)'

Volume

硬盘挂载,有云方式和各种不同的方式,具体可以参见 http://docs.kubernetes.org.cn/429.html#hostPath

emptyDir

Node 上的 Pod 一直运行,Volume 就会一直存,Pod 删除 Volume 删除

apiVersion: v1
// Pod对象
kind: Pod
metadata:
  name: test-pd
// 期望
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
   // volume挂载地址 /cache目录
    volumeMounts:
    - mountPath: /cache
   // 名称 cache-volume
      name: cache-volume
  // 实际的卷
  volumes:
  // 名称
  - name: cache-volume
   // 挂载模式
    emptyDir: {}

hostPath

hostPath 挂载机器上的文件到 Pod 里

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /data

Annotations

描述,可以应用于检索对象,类似标签

"annotations": {
  "key1" : "value1",
  "key2" : "value2"
}

Nodes

集群节点,工作节点

节点包含的状态信息

  • Address
  • Condition
  • Capacity
  • Info

Address

  • Hostname
  • ExternalIP
  • InternalIP

Condition

  • OutOfDisk
  • Ready
  • MemoryPressure
  • DiskPressure

Capacity

节点上的可用资源:CPU,内存,可调度最大 pod 数量

info

节点的基础信息,版本信息等

kubelet Self-Registration of Nodes

通过 kubelet 向 Master 节点注册自己

  • --api-servers - Location of the apiservers.
  • --kubeconfig - Path to credentials to authenticate itself to the apiserver.
  • --cloud-provider - How to talk to a cloud provider to read metadata about itself.
  • --register-node - Automatically register with the API server.
  • --register-with-taints - Register the node with the given list of taints (comma separated <key>=<value>:<effect>). No-op if register-node is false.
  • --node-ip IP address of the node.
  • --node-labels - Labels to add when registering the node in the cluster.
  • --node-status-update-frequency - Specifies how often kubelet posts node status to master.

Pod

Pod 是 Kubernetes 创建或部署的最小/最简单的基本单位,一个 Pod 代表集群上正在运行的一个进程。

一个 Pod 封装一个应用容器(也可以有多个容器),存储资源、一个独立的网络 IP 以及管理控制容器运行方式的策略选项。Pod 代表部署的一个单位:Kubernetes 中单个应用的实例,它可能由单个容器或多个容器共享组成的资源。

安全策略

Pod 安全策略 是集群级别的资源,它能够控制 Pod 运行的行为,以及它具有访问什么的能力。 PodSecurityPolicy 对象定义了一组条件,指示 Pod 必须按系统所能接受的顺序运行。 它们允许管理员控制如下方面:

图片.png

demo

PodSecurityPolicy 对象 YAML 配置文件

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
  name: permissive
spec:
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  hostPorts:
  - min: 8000
    max: 8080
  volumes:
  - '*'

创建 PodSecurityPolicy 对象

kubectl create -f  demo.yaml

查看所有配置的安全策略

kubectl get psp

修改安全策略

kubectl edit psp permissive

删除安全策略

kubectl delete psp permissive

生命周期

pause

  • Pending 挂起
  • Running 运行中
  • Succeeded 成功
  • Failed 失败
  • Unkonw 未知

容器探针

kubelet 定期对容器进行检测和诊断,执行诊断时 kubelet 调用容器的三种 Handler

  • ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
  • TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
  • HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。

每次探测都将获得以下三种结果之一:

  • 成功:容器通过了诊断。
  • 失败:容器未通过诊断。
  • 未知:诊断失败,因此不会采取任何行动。

Kubelet 可以选择是否执行在容器上运行的两种探针执行和做出反应:

  • livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success。
  • readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service
    的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。

restartPolicy: Always 或 OnFailure,Never 容器在探测失败时被杀死并重新启动

init 容器

  • Init 容器总是运行到成功完成为止。
  • 每个 Init 容器都必须在下一个 Init 容器启动之前成功完成。

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

demo
创建两个 service myservice 和 mydb

kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
---
kind: Service
apiVersion: v1
metadata:
  name: mydb
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9377
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
 // 最下面两个init跑完了才跑这个
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']


 // init容器
  initContainers:
  - name: init-myservice
    image: busybox
   // 等待myservice
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: busybox
  // 等待mydb
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

Pod 配置服务质量等级

当 Kubernetes 创建一个 Pod 时,它就会给这个 Pod 分配一个 QoS 等级:

  • Guaranteed
  • Burstable
  • BestEffort

QoS 等级为 Guaranteed:

  • Pod 里的每个容器都必须有内存限制和请求,而且必须是一样的。
  • Pod 里的每个容器都必须有 CPU 限制和请求,而且必须是一样的。

QoS 等级为 Burstable :

  • 该 Pod 不满足 QoS 等级 Guaranteed 的要求。
  • Pod 里至少有一个容器有内存或者 CPU 请求。

Pod BestEffort 等级, Pod 里的容器必须没有任何内存或者 CPU 的限制或请求。

QOS对象Kind name : Pod

优先级和抢占

为了启用该功能,需要在 API server 和 scheduler 的启动参数中设置

--feature-gates=PodPriority=true

在 API server 中还需要设置如下启动参数:

--runtime-config=scheduling.k8s.io/v1alpha1=true

kind PriorityClass优先级,通过value指定,数值越大优先级越高

apiVersion: v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for XYZ service pods only."

Pod生成后进入等待队列等待进行调度,如果没有一个节点能满足Pod的要求,那么会清除优先级较低的然后把Pod调度到那个节点上运行

PodPreset 将信息注入 Pods

将额外的运行时需求信息注入 pod。 使用标签选择器(label selector)来指定 Pod Preset 所适用的 pod。

正常Pod yaml

apiVersion: v1
kind: Pod
metadata:
  name: website
  labels:
    app: website
   // 标签role = frontend
    role: frontend
spec:
  containers:
    - name: website
      image: ecorp/website
      ports:
        - containerPort: 80

Pod Preset

kind: PodPreset
apiVersion: settings.k8s.io/v1alpha1
metadata:
  name: allow-database
  namespace: myns
spec:
  selector:
// 根据标签来选择准入POD
    matchLabels:
      role: frontend
  env:
    - name: DB_PORT
      value: "6379"
  volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
    - name: cache-volume
      emptyDir: {}

两者组合

apiVersion: v1
kind: Pod
metadata:
  name: website
  labels:
    app: website
    role: frontend
  annotations:
    podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
spec:
  containers:
    - name: website
      image: ecorp/website
      volumeMounts:
        - mountPath: /cache
          name: cache-volume
      ports:
        - containerPort: 80
      env:
        - name: DB_PORT
          value: "6379"
  volumes:
    - name: cache-volume
      emptyDir: {}

另有 ConfigMap配置方法,多 PodPreset配置方法
Pod Preset 与原 Pod 存在冲突时,Pod spec 不会被修改。

RS

ReplicaSet(RS)是 Replication Controller(RC)的升级版本。ReplicaSet 和 Replication Controller 之间的唯一区别是对选择器的支持。

ReplicaSet 能确保运行指定数量的 pod。然而,Deployment 是一个更高层次的概念,它能管理 ReplicaSets,并提供对 pod 的更新等功能。

apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
  name: frontend
  # these labels can be applied automatically
  # from the labels in the pod template if not set
  # labels:
    # app: guestbook
    # tier: frontend
spec:
  # this replicas value is default
  # modify it according to your case
  replicas: 3
  # selector can be applied automatically
  # from the labels in the pod template if not set,
  # but we are specifying the selector here to
  # demonstrate its usage.
  selector:
    matchLabels:
      tier: frontend
    matchExpressions:
      - {key: tier, operator: In, values: [frontend]}
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # If your cluster config does not include a dns service, then to
          # instead access environment variables to find service host
          # info, comment out the 'value: dns' line above, and uncomment the
          # line below.
          # value: env
        ports:
        - containerPort: 80

Deployment

Deployment 为 PodReplica Set(升级版的 Replication Controller)提供声明式更新。

  • 使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失败。
  • 通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
  • 如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision。
  • 扩容Deployment以满足更高的负载。
  • 暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
  • 根据Deployment 的状态判断上线是否hang住了。
  • 清除旧的不必要的 ReplicaSet。

demo

创建三个Nginx的Deployment

kubectl create -f https://kubernetes.io/docs/user-guide/nginx-deployment.yaml --record

查看Deployment

kubectl get deployments

预期是3个Replica,当前是0个,最新的是0个,可用0个

NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         0         0            0           1s

查看RS

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-2035384211   3         3         0       18s

查看当前POD

$ kubectl get pods --show-labels
NAME                                READY     STATUS    RESTARTS   AGE       LABELS
nginx-deployment-2035384211-7ci7o   1/1       Running   0          18s       app=nginx,pod-template-hash=2035384211
nginx-deployment-2035384211-kzszj   1/1       Running   0          18s       app=nginx,pod-template-hash=2035384211
nginx-deployment-2035384211-qqcnn   1/1       Running   0          18s       app=nginx,pod-template-hash=2035384211

Deployment 的 rollout 当且仅当 Deployment 的 pod template(例如.spec.template)中的label更新或者镜像更改时被触发。其他更新,例如扩容Deployment不会触发 rollout。

更新Deployment

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

查看rollout状态

$ kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out

我们通过执行kubectl get rs可以看到 Deployment 更新了Pod,通过创建一个新的 ReplicaSet 并扩容了3个 replica,同时将原来的 ReplicaSet 缩容到了0个 replica。

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-1564180365   3         3         0       6s
nginx-deployment-2035384211   0         0         0       36s

执行 get pods只会看到当前的新的 pod:

$ kubectl get pods
NAME                                READY     STATUS    RESTARTS   AGE
nginx-deployment-1564180365-khku8   1/1       Running   0          14s
nginx-deployment-1564180365-nacti   1/1       Running   0          14s
nginx-deployment-1564180365-z9gth   1/1       Running   0          14s

当新的Pod创建出来之前不会杀掉旧的Pod。这样能够确保可用的 Pod 数量至少有2个,Pod的总数最多4个。

$ kubectl describe deployments
Name:           nginx-deployment
Namespace:      default
CreationTimestamp:  Tue, 15 Mar 2016 12:01:06 -0700
Labels:         app=nginx
Selector:       app=nginx
Replicas:       3 updated | 3 total | 3 available | 0 unavailable
StrategyType:       RollingUpdate
MinReadySeconds:    0
RollingUpdateStrategy:  1 max unavailable, 1 max surge
OldReplicaSets:     <none>
NewReplicaSet:      nginx-deployment-1564180365 (3/3 replicas created)
Events:
  FirstSeen LastSeen    Count   From                     SubobjectPath   Type        Reason              Message
  --------- --------    -----   ----                     -------------   --------    ------              -------
  36s       36s         1       {deployment-controller }                 Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-2035384211 to 3
  23s       23s         1       {deployment-controller }                 Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-1564180365 to 1
  23s       23s         1       {deployment-controller }                 Normal      ScalingReplicaSet   Scaled down replica set nginx-deployment-2035384211 to 2
  23s       23s         1       {deployment-controller }                 Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-1564180365 to 2
  21s       21s         1       {deployment-controller }                 Normal      ScalingReplicaSet   Scaled down replica set nginx-deployment-2035384211 to 0
  21s       21s         1       {deployment-controller }                 Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-1564180365 to 3

回退

默认情况下,kubernetes 会在系统中保存前两次的 Deployment 的 rollout 历史记录

假设我们在更新 Deployment 的时候犯了一个拼写错误,将镜像的名字写成了nginx:1.91,而正确的名字应该是nginx:1.9.1:

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.91
deployment "nginx-deployment" image updated

Rollout 将会卡住。

$ kubectl rollout status deployments nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...

按住 Ctrl-C 停止上面的 rollout 状态监控。

您会看到旧的 replica(nginx-deployment-1564180365 和 nginx-deployment-2035384211)和新的 replica (nginx-deployment-3066724191)数目都是2个。

$ kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-1564180365   2         2         0       25s
nginx-deployment-2035384211   0         0         0       36s
nginx-deployment-3066724191   2         2         2       6s

看下创建 Pod,您会看到有两个新的 ReplicaSet 创建的 Pod 处于 ImagePullBackOff 状态,循环拉取镜像。

$ kubectl get pods
NAME                                READY     STATUS             RESTARTS   AGE
nginx-deployment-1564180365-70iae   1/1       Running            0          25s
nginx-deployment-1564180365-jbqqo   1/1       Running            0          25s
nginx-deployment-3066724191-08mng   0/1       ImagePullBackOff   0          6s
nginx-deployment-3066724191-eocby   0/1       ImagePullBackOff   0          6s

注意,Deployment controller会自动停止坏的 rollout,并停止扩容新的 ReplicaSet。

$ kubectl describe deployment
Name:           nginx-deployment
Namespace:      default
CreationTimestamp:  Tue, 15 Mar 2016 14:48:04 -0700
Labels:         app=nginx
Selector:       app=nginx
Replicas:       2 updated | 3 total | 2 available | 2 unavailable
StrategyType:       RollingUpdate
MinReadySeconds:    0
RollingUpdateStrategy:  1 max unavailable, 1 max surge
OldReplicaSets:     nginx-deployment-1564180365 (2/2 replicas created)
NewReplicaSet:      nginx-deployment-3066724191 (2/2 replicas created)
Events:
  FirstSeen LastSeen    Count   From                    SubobjectPath   Type        Reason              Message
  --------- --------    -----   ----                    -------------   --------    ------              -------
  1m        1m          1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-2035384211 to 3
  22s       22s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-1564180365 to 1
  22s       22s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled down replica set nginx-deployment-2035384211 to 2
  22s       22s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-1564180365 to 2
  21s       21s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled down replica set nginx-deployment-2035384211 to 0
  21s       21s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-1564180365 to 3
  13s       13s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-3066724191 to 1
  13s       13s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled down replica set nginx-deployment-1564180365 to 2
  13s       13s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-3066724191 to 2

检查下 Deployment 的 revision:

$ kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment":
REVISION    CHANGE-CAUSE
1           kubectl create -f https://kubernetes.io/docs/user-guide/nginx-deployment.yaml--record
2           kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
3           kubectl set image deployment/nginx-deployment nginx=nginx:1.91

查看单个revision 的详细信息:

$ kubectl rollout history deployment/nginx-deployment --revision=2
deployments "nginx-deployment" revision 2
  Labels:       app=nginx
          pod-template-hash=1159050644
  Annotations:  kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
  Containers:
   nginx:
    Image:      nginx:1.9.1
    Port:       80/TCP
     QoS Tier:
        cpu:      BestEffort
        memory:   BestEffort
    Environment Variables:      <none>

回退到历史版本

kubectl rollout undo deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment --to-revision=2

您可以通过设置.spec.revisonHistoryLimit项来指定 deployment 最多保留多少 revision 历史记录。默认的会保留所有的 revision;如果将该项设置为0,Deployment就不允许回退了。

Deployment 扩容

您可以使用以下命令扩容 Deployment:

$ kubectl scale deployment nginx-deployment --replicas 10

暂停

kubectl rollout pause deployment/nginx-deployment

恢复

kubectl rollout resume deploy nginx

Deployment 状态

progressing

  • Deployment 正在创建新的ReplicaSet过程中。
  • Deployment 正在扩容一个已有的 ReplicaSet。
  • Deployment 正在缩容一个已有的 ReplicaSet。
  • 有新的可用的 pod 出现。

complete

  • Deployment 最小可用。最小可用意味着 Deployment 的可用 replica 个数等于或者超过 Deployment 策略中的期望个数。
  • 所有与该 Deployment 相关的replica都被更新到了您指定版本,也就说更新完成。
  • 该 Deployment 中没有旧的 Pod 存在。

失败状态

  • 无效的引用
  • 不可读的 probe failure
  • 镜像拉取错误
  • 权限不够
  • 范围限制
  • 程序运行时配置错误

Service

负责网络转发地址解析Pod访问等

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

上述配置将创建一个名称为 “my-service” 的 Service 对象,它会将请求代理到使用 TCP 端口 9376,并且具有标签 "app=MyApp" 的 Pod 上。

在任何这些场景中,都能够定义没有 selector 的 Service :

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

由于这个 Service 没有 selector,就不会创建相关的 Endpoints 对象。可以手动将 Service 映射到指定的 Endpoints:

kind: Endpoints
apiVersion: v1
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 1.2.3.4
    ports:
      - port: 9376

Endpoint IP 地址不能是 loopback(127.0.0.0/8)、 link-local(169.254.0.0/16)、或者 link-local 多播(224.0.0.0/24)。

ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何的端口和 Endpoint。 相反地,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

Service 代理

在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。

userspace 代理模式

图片.png

iptables 代理模式

图片.png

多端口

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
    selector:
      app: MyApp
    ports:
      - name: http
        protocol: TCP
        port: 80
        targetPort: 9376
      - name: https
        protocol: TCP
        port: 443
        targetPort: 9377

服务发现

Kubernetes 支持2种基本的服务发现模式 —— 环境变量和 DNS。

环境变量

一个名称为 "redis-master" 的 Service 暴露了 TCP 端口 6379,同时给它分配了 Cluster IP 地址 10.0.0.11,这个 Service 生成了如下环境变量:

REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11

DNS

DNS 服务器监视着创建新 Service 的 Kubernetes API,从而为每一个 Service 创建一组 DNS 记录。 如果整个集群的 DNS 一直被启用,那么所有的 Pod 应该能够自动对 Service 进行名称解析。

服务类型

Kubernetes ServiceTypes 允许指定一个需要的类型的 Service,默认是 ClusterIP 类型。

  • ClusterIP:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。
  • NodePort:通过每个 Node 上的 IP
    和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。
  • LoadBalancer:使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
  • ExternalName:通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。
    没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。

外部 IP

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
  externalIPs: 
    - 80.11.12.10

Service查错

查看Service是否存在

kubectl get svc ServiceName

创建一个service,kubectl creat -f xxx.yml

apiVersion: v1
kind: Service
metadata:
  name: hostnames
spec:
  selector:
    app: hostnames
  ports:
  - name: default
    protocol: TCP
    port: 80
    targetPort: 9376

查看service是否通过DNS工作

nslookup hostnames

查看service的配置是否配置有误

$ kubectl get service hostnames -o json
{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "hostnames",
        "namespace": "default",
        "selfLink": "/api/v1/namespaces/default/services/hostnames",
        "uid": "428c8b6c-24bc-11e5-936d-42010af0a9bc",
        "resourceVersion": "347189",
        "creationTimestamp": "2015-07-07T15:24:29Z",
        "labels": {
            "app": "hostnames"
        }
    },
    "spec": {
        "ports": [
            {
                "name": "default",
                "protocol": "TCP",
                "port": 80,
                "targetPort": 9376,
                "nodePort": 0
            }
        ],
        "selector": {
            "app": "hostnames"
        },
        "clusterIP": "10.0.1.175",
        "type": "ClusterIP",
        "sessionAffinity": "None"
    },
    "status": {
        "loadBalancer": {}
    }
}

是否写入了Iptables规则

iptables-save | grep hostnames

根据label查看pod信息

 kubectl get pods -l run=my-nginx -o wide

检查 Pod 的 IP 地址:

kubectl get pods -l run=my-nginx -o yaml | grep podIP

某个节点死掉时,Pod会终止,Deployment将创建新的Pod,使用不同的IP,当创建时,每个Service被分配一个clusterIP集群内地址,如下

$ kubectl get svc my-nginx
NAME       CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
my-nginx   10.0.162.149   <none>        80/TCP    21s

然后添加到Service的Endpoints中

$ kubectl describe svc my-nginx
Name:                my-nginx
Namespace:           default
Labels:              run=my-nginx
Selector:            run=my-nginx
Type:                ClusterIP
IP:                  10.0.162.149
Port:                <unset> 80/TCP
Endpoints:           10.244.2.5:80,10.244.3.4:80
Session Affinity:    None
No events.

$ kubectl get ep my-nginx
NAME       ENDPOINTS                     AGE
my-nginx   10.244.2.5:80,10.244.3.4:80   1m

当 Pod 在 Node 上运行时,kubelet 会为每个活跃的 Service 添加一组环境变量。
查看Pod的环境变量

$ kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE
KUBERNETES_SERVICE_PORT=443
MY_NGINX_SERVICE_HOST=10.0.162.149
KUBERNETES_SERVICE_HOST=10.0.0.1
MY_NGINX_SERVICE_PORT=80
KUBERNETES_SERVICE_PORT_HTTPS=443

Kubernetes 提供了一个 DNS 插件 Service,它使用 skydns 自动为其它 Service 指派 DNS 名字。 如果它在集群中处于运行状态,可以通过如下命令来检查:

$ kubectl get services kube-dns --namespace=kube-system
NAME       CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns   10.0.0.10    <none>        53/UDP,53/TCP   8m

关于Service的安全问题

  • https 自签名证书(除非已经有了一个识别身份的证书)
  • 使用证书配置的 Nginx server
  • 使证书可以访问 Pod 的秘钥

配置证书的Service yaml

  • 它在相同的文件中包含了 Deployment 和 Service 的规格
  • Nginx server 处理 80 端口上的 http 流量,以及 443 端口上的 https 流量,Nginx Service 暴露了这两个端口。
  • 每个容器访问挂载在 /etc/nginx/ssl 卷上的秘钥。这需要在 Nginx server 启动之前安装好。
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 80
    protocol: TCP
    name: http
  - port: 443
    protocol: TCP
    name: https
  selector:
    run: my-nginx
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 1
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      volumes:
      - name: secret-volume
        secret:
          secretName: nginxsecret
      containers:
      - name: nginxhttps
        image: bprashanth/nginxhttps:1.0
        ports:
        - containerPort: 443
        - containerPort: 80
        volumeMounts:
       // 证书挂载目录
        - mountPath: /etc/nginx/ssl
          name: secret-volume

DNS Pod

DNS 是内置的服务,通过插件管理器 集群插件 自动被启动。
Kubernetes DNS 在集群中调度 DNS Pod 和 Service ,配置 kubelet 以通知个别容器使用 DNS Service 的 IP 解析 DNS 名字。

支持的 DNS 模式

  • A记录
  • SRV记录

查看Pod的DNS状态

kubectl exec -ti podName -- nslookup kubernetes.default

kubectl get pods --namespace=kube-system -l k8s-app=kube-dns

kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c kubedns

kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c dnsmasq

kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c healthz

垃圾收集

一些 Kubernetes 对象是其它一些的 Owner。例如,一个 ReplicaSet 是一组 Pod 的 Owner。具有 Owner
的对象被称为是 Owner 的 Dependent。每个 Dependent
对象具有一个指向其所属对象的 metadata.ownerReferences 字段。

控制垃圾收集器删除 Dependent

当删除对象时,可以指定是否该对象的 Dependent 也自动删除掉。自动删除 Dependent 也称为 级联删除。Kubernetes 中有两种 级联删除 的模式:background 模式和 foreground 模式。

如果删除对象时,不自动删除它的 Dependent,这些 Dependent 被称作是原对象的 孤儿。

Background 级联删除

在 background 级联删除 模式下,Kubernetes 会立即删除 Owner 对象,然后垃圾收集器会在后台删除这些 Dependent。

Foreground 级联删除

在 foreground 级联删除 模式下,根对象首先进入 “删除中” 状态。在 “删除中” 状态会有如下的情况:

  • 对象仍然可以通过 REST API 可见
  • 会设置对象的 deletionTimestamp 字段
  • 对象的 metadata.finalizers 字段包含了值 “foregroundDeletion”

一旦被设置为 “删除中” 状态,垃圾收集器会删除对象的所有 Dependent。垃圾收集器删除了所有 “Blocking” 的 Dependent之后,它会删除 Owner 对象。

K8s配置文件解析

apiVersion: v1 # 【必须】版本号
kind: Pod # 【必选】Pod
metadata: # 【必选-Object】元数据
  name: String # 【必选】 Pod的名称
  namespace: String # 【必选】 Pod所属的命名空间
  labels: # 【List】 自定义标签列表
    - name: String
  annotations: # 【List】 自定义注解列表
    - name: String
spec: # 【必选-Object】 Pod中容器的详细定义
  containers: # 【必选-List】 Pod中容器的详细定义
    - name: String # 【必选】 容器的名称
      image: String # 【必选】 容器的镜像名称
      imagePullPolicy: [Always | Never | IfNotPresent] # 【String】 每次都尝试重新拉取镜像 | 仅使用本地镜像 | 如果本地有镜像则使用,没有则拉取
      command: [String] # 【List】 容器的启动命令列表,如果不指定,则使用镜像打包时使用的启动命令
      args: [String] # 【List】 容器的启动命令参数列表
      workingDir: String # 容器的工作目录
      volumeMounts: # 【List】 挂载到容器内部的存储卷配置
        - name: String # 引用Pod定义的共享存储卷的名称,需使用volumes[]部分定义的共享存储卷名称
          mountPath: Sting # 存储卷在容器内mount的绝对路径,应少于512个字符
          readOnly: Boolean # 是否为只读模式,默认为读写模式
      ports: # 【List】 容器需要暴露的端口号列表
        - name: String  # 端口的名称
          containerPort: Int # 容器需要监听的端口号
          hostPort: Int # 容器所在主机需要监听的端口号,默认与containerPort相同。设置hostPort时,同一台宿主机将无法启动该容器的第二份副本
          protocol: String # 端口协议,支持TCP和UDP,默认值为TCP
      env: # 【List】 容器运行前需设置的环境变量列表
        - name: String # 环境变量的名称
          value: String # 环境变量的值
      resources: # 【Object】 资源限制和资源请求的设置
        limits: # 【Object】 资源限制的设置
          cpu: String # CPU限制,单位为core数,将用于docker run --cpu-shares参数
          memory: String # 内存限制,单位可以为MB,GB等,将用于docker run --memory参数
        requests: # 【Object】 资源限制的设置
          cpu: String # cpu请求,单位为core数,容器启动的初始可用数量
          memory: String # 内存请求,单位可以为MB,GB等,容器启动的初始可用数量
      livenessProbe: # 【Object】 对Pod内各容器健康检查的设置,当探测无响应几次之后,系统将自动重启该容器。可以设置的方法包括:exec、httpGet和tcpSocket。对一个容器只需要设置一种健康检查的方法
        exec: # 【Object】 对Pod内各容器健康检查的设置,exec方式
          command: [String] # exec方式需要指定的命令或者脚本
        httpGet: # 【Object】 对Pod内各容器健康检查的设置,HTTGet方式。需要指定path、port
          path: String
          port: Number
          host: String
          scheme: String
          httpHeaders:
            - name: String
              value: String
        tcpSocket: # 【Object】 对Pod内各容器健康检查的设置,tcpSocket方式
          port: Number
        initialDelaySeconds: Number # 容器启动完成后首次探测的时间,单位为s
        timeoutSeconds: Number  # 对容器健康检查的探测等待响应的超时时间设置,单位为s,默认值为1s。若超过该超时时间设置,则将认为该容器不健康,会重启该容器。
        periodSeconds: Number # 对容器健康检查的定期探测时间设置,单位为s,默认10s探测一次
        successThreshold: 0
        failureThreshold: 0
      securityContext:
        privileged: Boolean
  restartPolicy: [Always | Never | OnFailure] # Pod的重启策略 一旦终止运行,都将重启 | 终止后kubelet将报告给master,不会重启 | 只有Pod以非零退出码终止时,kubelet才会重启该容器。如果容器正常终止(退出码为0),则不会重启。
  nodeSelector: object # 设置Node的Label,以key:value格式指定,Pod将被调度到具有这些Label的Node上
  imagePullSecrets: # 【Object】 pull镜像时使用的Secret名称,以name:secretkey格式指定
    - name: String
  hostNetwork: Boolean # 是否使用主机网络模式,默认值为false。设置为true表示容器使用宿主机网络,不再使用docker网桥,该Pod将无法在同一台宿主机上启动第二个副本
  volumes: # 【List】 在该Pod上定义的共享存储卷列表
    - name: String # 共享存储卷的名称,volume的类型有很多emptyDir,hostPath,secret,nfs,glusterfs,cephfs,configMap
      emptyDir: {} # 【Object】 类型为emptyDir的存储卷,表示与Pod同生命周期的一个临时目录,其值为一个空对象:emptyDir: {}
      hostPath: # 【Object】 类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
        path: String # Pod所在主机的目录,将被用于容器中mount的目录
      secret: # 【Object】类型为secret的存储卷,表示挂载集群预定义的secret对象到容器内部
        secretName: String
        items:
          - key: String
            path: String
      configMap: # 【Object】 类型为configMap的存储卷,表示挂载集群预定义的configMap对象到容器内部
        name: String
        items:
          - key: String
            path: String

标题:kubernetes文档知识点个人总结
作者:ferried
地址:https://blog.eiyouhe.com/articles/2020/03/29/1585493374857.html