【Java劝退师】Kubernetes(K8S) 知识脑图 - 集群容器管理与协调工具

1,215 阅读16分钟

K8S

Kubernetes

集群容器管理与协调工具

一、功能

  1. 不停机情况下大规模持续布署容器
  2. 容器崩溃时自动修复与替换
  3. 容器间可远程共享存储数据

二、基础组件

集群至少要有 1 个主节点、1 个工作节点

主节点 负责管理 工作节点,工作节点 负责管理 Pod

多主节点 为集群提供 故障转移 与 高可用 - sealos

1. 主节点

  • kube-api-server

    • 提供集群管理的 REST API 接口,包含 认证授权、数据校验、集群状态 变更

    • 担任其他组件间数据交互的枢纽(组件信息都存在 etcd,访问 etcd 必须透过 API Sever)

  • etcd

    • 具备 一致性、高可用 的键值数据库,负责存储 节点、组件 信息

    • 通常最少布署 3 个节点

  • kube-sheduler

    • 负责监视尚未运行到节点的 Pod,并根据调度策略调度 Pod 到节点上

  • kube-controller-manager

    • 透过 API Sever 监控集群状态

    • 由一系列控制器组成,包含 Replication Controller 副本控制器、Node Controller 节点控制器、Deployment Controller 布署控制器

  • cloud-controller-manager

    • 负责与云提供商交互的控制器

2. 工作节点

  • kubelet

    • 管理 Pod 及 容器

    • 监听 10250 端口,接收 主节点 指令

    • 向 主节点 汇报 资源使用情况

  • kube-proxy

    • 从 API Server 获取所有 Server 信息
    • 根据 Server 信息创建代理,实现 Server 到 Pod 的 请求路由转发

三、资源类型

1. Namespace 命名空间

  • 对一组 资源 和 对象 的抽象集合,可视为 K8S 中的虚拟化集群,各命名空间逻辑上彼此隔离
  • 内置命名空间
    • default - 新创建资源默认属于此命名空间
    • kube-system - 供 K8S 系统组件使用
    • kube-node-lease - 供第三方插件监视 K8S 状态使用
    • kube-public - 供 公共资源 使用

2. Pod 容器封装

  • 一个 或 多个 容器的组合,这些容器共享 存储、网络、命名空间

  • K8S 能够调度的最小单位

  • 1 个 Pod 会被指派 1 个唯一的 IP 地址,Pod 中的每个容器共享此 IP 和 端口

  • Pod 中的所有容器共享存储卷

  • 默认 终止宽限期为 30 秒,超过宽限期将强制关闭,且 Pod 在 API Server 的状态将被更新为 dead

  • 相位(状态)

    • pending : API Server 已创建 Pod 资源并存入 etcd 中,但未完成调度
    • running : Pod 已被调度至特定节点,且容器已被创建完成
    • succeeded : Pod 中的容器被成功终止 且 不会被重启
    • failed : 容器已终止,但至少有 1 个容器终止异常(返回非 0 值退出或被系统终止)
    • unknown : API Server 无法获取到 Pod 状态
  • 重启策略 restartPolicy

    在宿主机上重启,而非调度到其他节点

    重启延时时长将随重启次数递增,最长为 300 秒

    • 【默认】Always - 只要退出就重启

    • OnFailure - 异常退出才重启

    • Never - 不会重启

  • 镜像拉取策略 imagePullPolicy

    • Always : 总是拉取

    • IfNotPresent : 如果本地有镜像,使用本地;如果本地没有,则拉取

    • Never : 只使用本地镜像,从不拉取

  • 生命周期

    • initC

      • 必须照顺序启动(前面的容器启动完,下一个容器才能启动),若 initC 启动失败,将不断重启直到成功
      • 若 Pod 对应的重启策略是 Never,将不会进行重启
    • postStart - 容器初始化完成运行

    • preStop - 容器终止前运行

  • 检测类型

    • 启动检测 startupProbe - 用于保护慢启动容器,检测成功才会交由 存活检测器 接手

    • 就绪检测 readinessProbe - 检测成功表示容器可以接收请求,将其 IP 添加到端点列表中

    • 存活检测 livenessProbe - 检测失败将重启容器

  • 检测方式

    • 请求检测 httpGet : 使用 HTTP 发出请求,响应码在 200~399 之间表示成功
    • 端口检测 tcpSocket : 端口开放则检测成功
    • 命令检测 exec : 命令返回 0 表示成功,否则则视为失败

3. Controller 控制器

负责管理 Pod

  • Deployment 布署控制器
    • 用于发布【无状态】应用
    • 封装了 ReplicaSet,可对 Pod 进行规模 布署 与 裁减
    • 可以进行 镜像升级 或 回滚
    • 默认保留前 2 次 rollout 历史纪录
    • 更新策略
      • 【默认】RollingUpdate 滚动更新 : 有一部分的 Pod 正在创建,一部分的 Pod 正在删除
      • Recreate 重建更新 : 删一个建一个
  • StatefulSet 状态集控制器
    • 用于发布【有状态】应用
    • 每个 Pod 都有 稳定、唯一 的网络标示
    • Pod 启、停 顺序受控
    • 透过 PV、PVC 实现持久化存储卷
    • 组成
      • Headless Service
        • 定义 Pod 网络标示
        • 没有 Cluster IP
      • StatefulSet : 具体应用
      • VolumeClaimTemplates
        • 存储卷申请模板
        • 为每个 Pod 生成不同的 PVC,并绑定 PV,让每个 PVC 中的数据都是不同的
  • DaemonSet 守护控制器
    • 在每个节点上运行 1 个应用
    • 常用于 监控、日志收集
  • Job 任务控制器
    • 运行一次性任务
    • 启动容错次数,默认 6 次
    • 重启时间间隔依次递增
  • CronJob 周期任务控制器 - 运行周期性任务

4. Service 服务

定义 K8S 访问规则

类型

  • 【默认】ClusterIP : 分配一个 K8S 内部可以访问的虚拟 IP
  • NodePort : 分配一个端口让外部可以访问
  • LoadBalancer : 使用云供应商的负载均衡器,可以路由到 ClusterIP 或 NodePort
  • ExternalName : 可以将服务映射到域名上

端口

  • target-port - 容器内应用的端口号
  • port - 暴露给集群内其他应用的端口号
  • node-port - 供外部访问的端口号 (30000-32767)

5. Ingress-nginx 入口

外部访问 K8S 集群的入口

  • 进入 K8S 集群请求的路由规则集合
  • 原理 - 根据 Ingress 规则(yml文档),动态更改 Nginx 配置文档,并进行 reload

6. Secret 安全

  • Service Account
    • 用于访问 K8S 的 API
    • 由 K8S 自动创建,并自动挂载到 Pod
    • 帐户
      • User 用户帐户 : 针对人
      • Service Account 服务帐户 : 针对进程
    • 角色
      • Role 普通角色 : 作用范围为特定命名空间
      • Cluster Role 集群角色 : 作用范围为整个 K8S
    • 绑定
      • RoleBinding 角色绑定 : 将角色权限赋予给帐户
      • ClusterRoleBinding 集群角色绑定 : 将集群角色权限赋予给帐户
  • Opaque : 保存 密码、密钥
  • kubernetes.io/dockerconfigjson : 存储私有 docker registry 的认证信息

7. ConfigMap 配置文档

用于保存配置数据的键值对

8. Label 标签

用于将某些服务固定在特定宿主机上 nodeSelector

# 语法 kubectl label nodes <node-name> <label-key>=<label-value>

# 给 Node 添加标签
kubectl label nodes k8s-node01 mariadb=mariadb10.5 --overwrite

# 查看 Node 标签
kubectl get nodes --show-labels

# 删除 k8s-node01 的 mariadb 标签 (最后面有'-')
kubectl label nodes k8s-node01 mariadb-

9. Volumn 存储卷

  • hostPath
    • 将宿主机 目录 或 文档 挂载到 Pod 中
    • 每个节点都要有,因为不确定容器会被分配到哪个节点
    • 只支持 ReadWriteOnce 模式(单节点 读/写 模式)
  • emptyDir
    • 临时目录,在 Pod 被移除时也会被一并删除
    • 用于同一 Pod 内多容器文档共享

10. PV & PVC

  • PV 持久化卷

    • 集群级别资源,不属于任何 Namespace

    • 使用 PV 需要透过 PVC 申请

    • 底层可以透过 Ceph、GlusterFS、NFS ... 等方式实现

    • 生命周期

      • Available 可用 : 尚未与 PVC 绑定
      • Bound 已绑定 : 已经与某个 PVC 绑定
      • Released 已释放 : 与之绑定的 PVC 已被删除,但其资源尚未被 K8S 回收
      • Failed 失败 : K8S 自动回收 PV 失败
    • 存储卷模式 volumeMode

      • 【默认】Filesystem : 文档系统
      • Block : 块设备
    • 访问模式 accessModes

      • ReadWriteOnce : 卷可以被 单节点 以 读/写 模式挂载

      • ReadOnlyMany : 卷可以被 多节点 以 只读 模式挂载

      • ReadWriteMany : 卷可以被 多节点 以 读/写 模式挂载

      HostPath 只支持 ReadWriteOnce 模式

      NFS 3 种模式都支持

    • 回收策略 persistentVolumeReclaimPolicy

      • 保留 Retain : 保留数据,需由管理员手动清理
      • 回收 Recycle : 删除数据 - HostPath、NFS 支持
      • 删除 Delete : 删除存储资源 - 云存储系统支持
  • PVC 持久化卷声明

    • 用于对 PV 资源申请

    • 属于一个 Namespace 资源

    PV 与 PVC 是 一对一 绑定

    一个 PVC 可以被多个 Pod 挂载

四、命令语法格式

kubectl [command] [TYPE] [NAME] [flags]

  • command 对资源的操作

    • create - 创建资源
    • get - 列出资源
      • 参数
        • -o 格式类型 : 自定义输出格式
          • wide : 附加信息
          • yaml : YAML 格式
        • -w : 动态更新
    • describe - 显示详细状态
    • apply - 运行资源
    • delete - 删除资源
    • exec - 运行命令
    • logs - 打印日志
  • TYPE 资源类型

    • cluster-info - 集群状态
    • configmaps - cm - 配置文档
    • namespaces - ns - 命名空间
    • nodes - no - 节点
    • pods - po - 容器封装
    • persistentvolumeclaims - pvc - 存储卷声明
    • persistentvolumes - pv - 存储卷
    • secrets - 安全
    • serviceaccounts - sa - 服务帐户
    • services - svc - 服务
    • daemonsets - ds - 守护控制器
    • deployments - deploy - 布署控制器
    • statefulsets - sts - 状态集控制器
    • ingresses - ing - 入口
  • NAME 资源名称

    • 若省略则指该资源类型下的所有资源
    • 操作 同资源类型 下的某些资源 - kubectl get pod example-pod1 example-pod2
    • 操作 多个资源类型 - kubectl get pod/example-pod1 replicationcontroller/example-rc1
    • 操作 文档指定资源 - kubectl get pod -f ./pod.yaml -f ./depolyment.yaml
  • flags 可选参数

    会覆盖 默认值 与 环境变量

    -n <命名空间> : 指定命名空间

    -c <容器名> : 指定容器

    -l name=<标签名> : 指定标签名

    --all : 所有

    --force : 强制

五、YML 资源创建

1. Pod 容器封装

apiVersion: v1
kind: Pod # 资源类别
metadata: # 资源元数据
  name: tomcat9
  labels:
  	app: tomcat9
spec:
  containers:
    - name: tomcat9
      image: tomcat:9.0.20-jre8-alpine
      imagePullPolicy: IfNotPresent # 镜像拉取策略
      
      startupProbe: 				 # 启动检测,检测成功后,存活检测才会启动
        httpGet: 						 # 使用 HTTP 请求检测,响应码在 200~399 之间表示成功
        	port: 8080 				 # 检测端口
          path: /index1.html # 检测路径
        failureThreshold: 30 # 检测失败最大次数
        periodSeconds: 10 	 # 检测间隔
        
      livenessProbe: 				 # 存活检测
        exec: 							 # 使用命令检测,命令返回 0 表示成功,否则则视为失败
        	command: ["test","-e","/tmp/livenesspod"] # 查看文档是否存在
        initialDelaySeconds: 1
        periodSeconds: 3
      
      readinessProbe: 			 # 就绪检测
       	tcpSocket: 					 # 端口检测
        	port: 8080
        initialDelaySeconds: 10
        periodSeconds: 3
        timeoutSeconds: 5
        
        
      lifecycle:
        postStart: # 在 postStart 生命周期运行命令
          exec:
          	command: ['mkdir','-p','/lagou/k8s/index.html']
                
     	        
  restartPolicy: Always # 重启策略

2. Deployment 布署控制器

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deployment
  labels:
  	app: tomcat-deployment
spec:
  replicas: 3 # 副本数量
  template:
  	metadata:
      name: tomcat-deployment
      labels:
      	app: tomcat-pod # 标签
    spec:
    	nodeName: k8s-node02 # 使用节点名称决定固定要运行的节点
    	nodeSelector: # 使用标签决定固定要运行的节点
        mariadb: mariadb # 运行节点的标签 key: value
      containers: # 定义 Pod 相关内容
        - name: tomcat-cotainer
          image: tomcat:9.0.20-jre8-alpine
          imagePullPolicy: IfNotPresent # 镜像拉取策略
          ports:
			- containerPort: 8080 # 容器内应用的端口号
      restartPolicy: Always # 重启策略
  selector: # 圈定 Deployment 管理的 Pod 范围
    matchLabels:
    	app: tomcat-pod # Deployment 必须存在属性,需与 spec.template.metadata.labels.app 属性对应
    	
  strategy: # 更新策略
    type: RollingUpdate

容器升级

# 更改配置文档
kubectl edit deployments.apps tomcat-deployment

容器扩容

kubectl scale deployment tomcat-deployment --replicas=15

滚动更新

# 更新 tomcat-deployment 的 tomcat-cotainer 容器,替换成 tomcat:alpine 镜像,并且滚动暂停 tomcat-deployment
kubectl set image deployment tomcat-deployment tomcat-cotainer=tomcat:alpine && kubectl rollout pause deployment tomcat-deployment

# 观察更新状态
kubectl rollout status deployments tomcat-deployment

# 观察 Pod 状态
kubectl get pods -l app=tomcat-pod -w

# 继续滚动更新
kubectl rollout resume deploy tomcat-deployment

版本回退

# 查看 rollout 操作历史
kubectl rollout history deployment tomcat-deployment

# 查看 rollout 操作状态
kubectl rollout status deployment tomcat-deployment

# 进行版本回退
kubectl rollout undo deployment tomcat-deployment

3. StatefulSet 状态集控制器

Headless Service

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

StatefulSet

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: nginx-statefulset
  namespace: default
spec:
  serviceName: my-service # 指定要绑定的 Headless Service 名称
  replicas: 3
  selector:
    matchLabels:
    	app: nginx
  template:
    metadata:
      labels:
      	app: nginx
  spec:
    containers:
    - name: nginx
      image: nginx:latest
      ports:
      	- containerPort: 80

4. Service 服务

定义 K8S 访问规则

apiVersion: v1
kind: Service
metadata:
	name: tomcat-svc
spec:
  selector:
  	app: tomcat-pod # 需要与控制器的 spec.selector.matchLabels.app 属性对应
  ports:
    - port: 8888 # 暴露给集群内其他应用的端口号
      targetPort: 8080 # 容器内应用的端口号
      nodePort: 30088 # 供外部访问的端口号
      protocol: TCP
  type: NodePort # 让外部可以访问服务

5. DaemonSet 守护控制器

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: demonsetdemo
  labels:
  	app: demonsetdemo
spec:
  template:
    metadata:
    name: demonsetdemo
    labels:
    	app: demonsetdemo
  spec:
    containers:
      - name: demonsetdemo
        image: nginx:1.17.10-alpine
        imagePullPolicy: IfNotPresent
    restartPolicy: Always
  selector:
    matchLabels:
    	app: demonsetdemo

6. Job 任务控制器

apiVersion: batch/v1
kind: Job
metadata:
	name: pi
spec:
  template:
    spec:
      containers:
        - name: pi
          image: perl:slim
          command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(6000)"]
      restartPolicy: Never
  backoffLimit: 4 # 启动容错次数

7. Ingress 入口

ingress-nginx-svc : 定义对外访问规则,映射 Nginx 容器端口

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: 80
      nodePort: 31188 # 固定对外访问端口
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      nodePort: 30443 # 固定对外访问端口
      protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

nginx-ingress-controller : 负责转发 Nginx 请求给 Service

github.com/kubernetes/…

apiVersion: apps/v1
kind: DaemonSet # 改成 Daemonset,让所有节点都运行此控制器
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  # replicas: 1 # Daemonset 不需设置副本数
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      annotations:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "true"
    spec:
      # wait up to five minutes for the drain of connections
      hostNetwork: true # 使用节点的网络
      terminationGracePeriodSeconds: 300
      serviceAccountName: nginx-ingress-serviceaccount
      nodeSelector:
        kubernetes.io/os: linux
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            - --annotations-prefix=nginx.ingress.kubernetes.io
          securityContext:
            allowPrivilegeEscalation: true
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            # www-data -> 101
            runAsUser: 101
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports: # Nginx 容器端口
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown
                  
---
# CPU、内存限制
apiVersion: v1
kind: LimitRange
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  limits:
  - min:
      memory: 90Mi
      cpu: 100m
    type: Container

Ingress : 定义路由转发规则,供 Ingress Controller 使用

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress-test
spec:
  rules:
    - host: ingress-tomcat.lagou.com
      http:
        paths:
          - path: /
            backend:
              serviceName: tomcat-svc # 转发目标的服务名称
              servicePort: 8080  # 容器的端口

Deployment、Service : 定义自己需要的控制器与服务

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deployment
  labels:
    app: tomcat-deployment
spec:
  replicas: 1
  template:
    metadata:
      name: tomcat-deployment
      labels:
        app: tomcat-deployment
    spec:
      containers:
        - name: tomcat-deployment
          image: tomcat:9.0.20-jre8-alpine
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
      restartPolicy: Always
  selector:
    matchLabels:
      app: tomcat-deployment
---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
spec:
  selector:
    app: tomcat-deployment
  ports:
    - port: 8080
      targetPort: 8080
      nodePort: 30088
  type: NodePort

8. Opaque Secret 密码

apiVersion: v1
kind: Secret
metadata:
	name: mariadbsecret
type: Opaque
  data:
  password: YWRtaW4=
            env:
              - name: MYSQL_ROOT_PASSWORD
                valueFrom: 
                  secretKeyRef: # 表示使用 Secret 服务
                    key: password
                    name: mariadbsecret # 这里改成 Secret 的 metadata.name
              - name: TZ
              	value: Asia/Shanghai

9. ConfigMap 配置文档

# 将配置文档转换成 ConfigMap
kubectl create configmap mysqlini --from-file=配置文档
kubectl get configmap mysqlini -o yaml > mariadbconfigmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mariadbconfigmap # 设置 ConfigMap 名称
data:
  my.cnf: "# MariaDB database server configuration file.\n#\n# You can copy this file
    to one of:\n# - \"/etc/mysql/my.cnf\" to set global options,\n# - \"~/.my.cnf\" # 以下 data 省略 
    spec:
      containers:
        - name: mariadb-deploy
          image: mariadb:10.5.2
          imagePullPolicy: IfNotPresen

          volumeMounts:
            - mountPath: /etc/mysql/mariadb.conf.d/ # 容器内的挂载目录
            	name: lagoumariadb # 必须与 volumes.name 一致

      volumes:
        - name: lagoumariadb # 必须与 spec.template.spec.containers.volumeMounts.name 一致
          configMap:
            name: mariadbconfigmap # 设置要引用的 ConfigMap

10. Volumn 存储卷

	spec:
      containers:
        - name: mariadb-deploy
          image: mariadb:10.5.2
          imagePullPolicy: IfNotPresen

          volumeMounts:
            - mountPath: /etc/mysql/mariadb.conf.d/ # 容器内的挂载目录
            	name: mariadb-volumn # 必须与 volumes.name 一致

      volumes:
        - name: mariadb-volumn # 必须与 spec.template.spec.containers.volumeMounts.name 一致
          hostPath:
            path: /data/mariadb # 宿主机目录
            type: Directory

11. PV&PVC 持久化卷

PV

apiVersion: v1
kind: PersistentVolume
metadata:
  labels:
  	app: mariadb-pv
  name: data-mariadb-pv
spec:
  accessModes:
  	- ReadWriteOnce # 读写一对一模式
  capacity:
  	storage: 10Gi # PV 容量
  hostPath:
    path: /data/mariadb
    type: DirectoryOrCreate
  persistentVolumeReclaimPolicy: Retain
  storageClassName: my-pv # 需与 PVC 的 spec.storageClassName 对应
  volumeMode: Filesystem

PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mariadb-pvc
  labels:
  	app: mariadb-pvc # 定义资源名称,供 控制器 使用
spec:
  accessModes:
  	- ReadWriteOnce # 读写一对一模式
  storageClassName: my-pv # 需与 PV 的 spec.storageClassName 对应
  resources:
  	requests:
  		storage: 1Gi # PVC 申请存储空间大小

Deployment

    spec:
      containers:
        - name: mariadb-deploy
          image: mariadb:10.5.2
          volumeMounts:
            - mountPath: /var/lib/mysql # 容器内的挂载目录
              name: volume-mariadb # 表示使用下方 volumes 定义的 volume-mariadb 资源
      volumes:
        - name: volume-mariadb # 必须与 spec.template.spec.containers.volumeMounts.name 一致
          persistentVolumeClaim:
            claimName: mariadb-pvc # 需与 PVC 的 metadata.labels.app 一致

12. Service Account 服务帐户

Role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default # 指定作用的命名空间
  name: pod-reader
rules:
- apiGroups: [""] # "" 指定核心 API 组
  resources: ["pods"] # 指定此权限的作用的资源类型
  verbs: ["get", "watch", "list"] # 指定权限

ClusterRole

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # namespace 省略掉,因为 ClusterRoles 是没有命名空间的
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

RoleBinding

# 此角色绑定使得用户 "jane" 能够读取 "default" 命名空间中的 Pods
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods 
  namespace: default
subjects:
- kind: User
  name: jane # 用户名称
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role # 确定 Role 或 ClusterRole 的类型
  name: pod-reader # 指定要绑定的 Role 或 ClusterRole 的名称
  apiGroup: rbac.authorization.k8s.io

13. 动态 NFS

StorageClass : 保存空间声明

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage # 需与 PVC 的 storageClassName 保持一致
  annotations:
    storageclass.kubernetes.io/is-default-class: "true" # 设置为默认的 storageclass
provisioner: nfs-client                                 # 动态卷分配者名称,需与 Deployment 的 spec.template.spec.containers.env.PROVISIONER_NAME 一致
parameters:
  archiveOnDelete: "true"                               # 设置为"false"时删除PVC不会保留数据,"true"则保留数据
mountOptions:
  - hard                                                # 指定为硬挂载方式
  - nfsvers=4                                           # 指定NFS版本,这个需要根据 NFS Server 版本号设置

Deployment : 具体 NFS 实现

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
 	# 设置升级策略为删除再创建(默认为滚动更新)
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner # 设置允许访问的 serviceAccount
      containers:
        - name: nfs-client-provisioner
          image: vbouchaud/nfs-client-provisioner:v3.1.1
          volumeMounts:
            - name: nfs-client-root # 需与 volumes.name 保持一致
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: nfs-client     # 需与 StorageClass 的 provisioner 保持一致
            - name: NFS_SERVER
              value: 192.168.198.156   # NFS 服务器地址,与 volumes.nfs.servers 保持一致
            - name: NFS_PATH
              value: /nfs/data         # NFS 服务共享目录地址,与 volumes.nfs.path 保持一致
      volumes:
        - name: nfs-client-root				 # 需与 volumeMounts.name 保持一致
          nfs:
            server: 192.168.198.156    # NFS 服务器地址,与 spec.containers.env.value 保持一致
            path: /nfs/data            # NFS 服务器目录,与 spec.containers.env.value 保持一致

StatefulSet : 具体应用

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginxdeployment
  labels:
    app: nginxdeployment
spec:
  replicas: 3
  serviceName: nginxsvc 
  template:
    metadata:
      name: nginxdeployment 
      labels:
        app: nginxdeployment # 需与 Headless Service 的 metadata.name 保持一致
    spec:
      containers:
        - name: nginxdeployment
          image: nginx:1.17.10-alpine
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /usr/share/nginx/html # 容器中要挂载的目录
              name: nginxvolume # 需与 volumeClaimTemplates.metadata.name 保持一致
      restartPolicy: Always
  volumeClaimTemplates: # 存储卷申请模板
    - metadata:
        name: nginxvolume # 需与 volumeMounts.name 保持一致
        annotations:
          volume.beta.kubernetes.io/storage-class: "nfs-storage" # 需与 StorageClass 的 metadata.name 保持一致
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 2Gi
  selector:
    matchLabels:
      app: nginxdeployment # 需与 spec.template.metadata.labels.app 保持一致

Headless Service : 定义 Pod 网络标示

apiVersion: v1
kind: Service
metadata:
  name: nginxsvc # 需与 StatefulSet 的 spec.serviceName 保持一致
spec:
  selector:
    app: nginxdeployment # 需与 StatefulSet 的 spec.template.metadata.labels.app 保持一致
  ports:
    - port: 80 # 设置容器端口
  clusterIP: None

六、调度策略

1. 资源分类

  • 可压缩资源
    • 可以被限制或回收
    • CPU、IO
  • 不可压缩资源
    • 不杀掉 Pod 就无法回收
    • 内存、硬盘

2. 节点亲和性

定义在 Pod 上,仅对新建的 Pod 有效,因规则改变导致节点内的 Pod 不符合调度规则时,不会将 Pod 移除

  • 硬亲和性

    • 调度规则不满足时,Pod 将处于 Pending 状态
  • 软亲和性

    • 调度规则不满足时,Pod 会被调度到一个不匹配的节点

3. 污点

  • 定义在 Node 节点上,用于拒绝将 Pod 调度于其上

4. 容忍度

  • 定义在 Pod 上的键值属性,用于配置可容忍污点
  • 调度器会将 Pod 调度到 能容忍污点 或 没有污点 的节点上