K8S实战进阶

打印 上一主题 下一主题

主题 955|帖子 955|积分 2865

title = ‘K8S实战进阶’
date = 2024-04-02T16:57:36+08:00
draft = true
+++
一、搭建Kubernetes集群

1.1 搭建方案

1.1.1 minikube

minikube 是一个工具, 能让你在本地运行 Kubernetes。 minikube 在你的个人计算机(包罗 Windows、macOS 和 Linux PC)上运行一个一体化(all-in-one)或多节点的本地 Kubernetes 集群,以便你来尝试 Kubernetes 或者开展每天的开发工作。
官方安装文档
1.1.2 kubeadm

你可以使用 kubeadm 工具来创建和管理 Kubernetes 集群。 该工具能够执行须要的动作并用一种用户友爱的方式启动一个可用的、安全的集群。
安装 kubeadm 展示了怎样安装 kubeadm 的过程。一旦安装了 kubeadm, 你就可以使用它来创建一个集群。
服务器要求

IP地址:


  • k8s-master:192.168.122.100
  • k8s-node1:192.168.122.110
  • k8s-node2:192.168.122.120
最低设置:2核、2G内存、20G硬盘
需要联网,不能联网的话需要提供对应镜像的私有仓库
软件环境

操作体系:Debian 12
Docker版本:Docker version 26.0.0
K8S版本:1.23.17(1.24移除了docker支持)
安装步骤


  • 初始操作
    1. #关闭防火墙
    2. systemctl stop firewalld    #停止firewalld服务
    3. systemctl disable firewalld    #firewalld禁止自启
    4. ufw disable    #ufw禁用
    5. #关闭selinux
    6. sed -i 's/enforcing/disabled/' /etc/selinux/config  #永久
    7. setenforce 0    #临时
    8. #关闭swap(关闭swap后,需要重启主机)
    9. swapoff -a    #临时
    10. sed -ri 's/.*swap.*/#&/' /etc/fstab    #永久
    11. free -h    #查看内存
    12. #根据规划设置主机名
    13. vim /etc/hostname
    14. #将桥接的IPv4流量传递到iptablesd的链路
    15. cat > /etc/sysctl.d/k8s.conf << EOF
    16. net.bridge.bridge-nf-call-ip6tables = 1
    17. net.bridge.bridge-nf-call-iptables = 1
    18. EOF
    19. sysctl --system    #生效
    20. #时间同步
    21. yum install ntpdate -y
    22. ntpdate ntp.aliyun.com
    23. apt install -y ntp
    24. ntpdate ntp.aliyun.com
    复制代码
  • 安装底子软件(全部节点)

    • 安装docker
      docker安装官方文档
      1. #卸载旧版本docker
      2. for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
      3. #设置Docker的存储库
      4. # Add Docker's official GPG key:
      5. sudo apt-get update
      6. sudo apt-get install ca-certificates curl
      7. sudo install -m 0755 -d /etc/apt/keyrings
      8. sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
      9. sudo chmod a+r /etc/apt/keyrings/docker.asc
      10. # Add the repository to Apt sources:
      11. echo \
      12.   "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
      13.   $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
      14.   sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
      15. sudo apt-get update
      16. #安装Docker包
      17. sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
      18. #配置docker镜像加速
      19. sudo tee /etc/docker/daemon.json <<-'EOF'
      20. {
      21.   "registry-mirrors": ["https://URL.mirror.aliyuncs.com"]
      22. }
      23. EOF
      24. sudo systemctl daemon-reload
      25. sudo systemctl restart docker
      26. #测试
      27. sudo docker run hello-world
      复制代码
    • 添加阿里云软件源
      阿里云镜像站安装文档
      1. #设置kubernetes存储库
      2. apt-get update && apt-get install -y apt-transport-https
      3. curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
      4. # 排错:
      5. # 执行curl命令报错:curl: (23) Failed writing body
      6. # 解决方案:curl -s -N https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
      7. # 执行命令报错:E: gnupg, gnupg2 and gnupg1 do not seem to be installed, but one of them is required for this operation
      8. # 解决方案:apt-get install -y gnupg2
      9. # 弹出警告:Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).(apt-key已弃用)
      10. # 解决方案:建议无视或者curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/apt-key.gpg --import
      11. cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
      12. deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
      13. EOF
      复制代码
    • 安装kubeadm、kubelet、kubectl
      1. #安装kubernetes
      2. apt-get update
      3. apt-cache madison kubelet    #查询版本号
      4. apt-get install -y kubelet=1.23.17-00 kubeadm=1.23.17-00 kubectl=1.23.17-00
      5. #测试
      6. kubectl version
      7. #设置开机自启
      8. systemctl enable kubelet.service
      9. # 查看docker设备信息
      10. docker info | grep Driver
      11. Cgroup Driver: systemd
      12. # 如果显示以下信息则需要更改
      13. docker info | grep Driver
      14. Cgroup Driver: cgroupfs
      15. # 配置关闭 Docker 的 cgroups
      16. vim /etc/docker/daemon.json  加入以下内容
      17. "exec-opts": ["native.cgroupdriver=systemd"]
      18. # 重启 docker
      19. systemctl daemon-reload
      20. systemctl restart docker
      复制代码

  • 部署Kubernetes Master
    1. #初始化master节点
    2. kubeadm init \
    3.       --apiserver-advertise-address=192.168.122.100 \
    4.       --image-repository registry.aliyuncs.com/google_containers \
    5.       --kubernetes-version v1.23.17 \
    6.       --service-cidr=10.96.0.0/12 \
    7.       --pod-network-cidr=10.244.0.0/16
    8.       
    9. #安装成功后,复制如下配置并执行
    10. mkdir -p $HOME/.kube
    11. sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    12. sudo chown $(id -u):$(id -g) $HOME/.kube/config
    13. kubectl get nodes
    复制代码
  • 加入Kubernetes Node
    1. #分别在 k8s-node1 和 k8s-node2 执行
    2. kubeadm join 192.168.122.100:6443 --token 47pvys.orya0t0d8fjcqhwj \
    3.         --discovery-token-ca-cert-hash sha256:314d290d2734a305e4a7220067f38f34dd0f6cdf349b983f09dba99a7843ce6f
    4.         
    5. # 如果初始化的 token 不小心清空了,可以通过如下命令获取或者重新申请
    6. # 如果 token 已经过期,就重新申请
    7. kubeadm token create
    8. # token 没有过期可以通过如下命令获取
    9. kubeadm token list
    10. # 获取 --discovery-token-ca-cert-hash 值,得到值后需要在前面拼接上 sha256:
    11. openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
    12. openssl dgst -sha256 -hex | sed 's/^.* //'
    复制代码
  • 部署CNI网络插件
    可选择Flannel、Calico、Canal 和 Weave
    Flannel官方文档与项目地址
    Calico官方文档
    Calico项目地址
    1. #在master节点上执行
    2. #下载 calico 配置文件(也可以使用Flannel、Canal和Weave)
    3. curl https://calico-v3-25.netlify.app/archive/v3.25/manifests/calico.yaml -O
    4. # 修改 calico.yaml 文件中的 CALICO_IPV4POOL_CIDR 配置,修改为与初始化的 cidr 相同(默认注释状态,会使用初始化时指定pod网络状态的配置)
    5. # Calico默认会拉取docker.io中的镜像,可以删除镜像 docker.io/ 前缀,避免下载过慢导致失败
    6. sed -i 's#docker.io/##g' calico.yaml
    7. #构建Calico网络
    8. kubectl apply -f calico.yaml
    复制代码
  • 测试Kubernetes集群
    1. #创建部署
    2. kubectl create deployment nginx --image=nginx
    3. #暴露端口
    4. kubectl expose deployment nginx --port=80 --type=NodePort
    5. #查看 pod 以及服务信息
    6. kubectl get pod,svc
    7. #宿主机访问测试
    复制代码
1.1.3 二进制安装

使用 k8s 官方 github 仓库下载二进制包安装,安装过程较复杂,但相对较为稳定,保举生产环境使用。
1.1.4 下令行工具安装

1.2 下令行工具kubectl

Kubernetes 提供 kubectl 是使用 Kubernetes API 与 Kubernetes 集群的控制面进行通讯的下令行工具。
这个工具叫做 kubectl。
更多下令
1.2.1 下令主动补全

  1. apt install bash-completion
  2. source /usr/share/bash-completion/bash_completion
  3. #所有用户自动补全
  4. kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null
  5. #当前用户自动补全
  6. echo 'source <(kubectl completion bash)' >> ~/.bashrc
  7. source ~/.bashrc
复制代码
1.2.2 在恣意节点使用kubectl

  1. # 1. 将 master 节点中 /etc/kubernetes/admin.conf 拷贝到需要运行的服务器的 /etc/kubernetes 目录中
  2. scp /etc/kubernetes/admin.conf root@k8s-node1:/etc/kubernetes
  3. scp /etc/kubernetes/admin.conf root@k8s-node2:/etc/kubernetes
  4. # 2. 在对应的服务器上配置环境变量
  5. echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
  6. source ~/.bash_profile
复制代码
1.2.3 资源操作

创建对象

  1. $ kubectl create -f ./my-manifest.yaml           # 创建资源
  2. $ kubectl create -f ./my1.yaml -f ./my2.yaml     # 使用多个文件创建资源
  3. $ kubectl create -f ./dir                        # 使用目录下的所有清单文件来创建资源
  4. $ kubectl create -f https://git.io/xxx         # 使用 url 来创建资源
  5. $ kubectl run nginx --image=nginx                # 启动一个 nginx 实例
  6. $ kubectl explain pods,svc                       # 获取 pod 和 svc 的文档
  7. # 从 stdin 输入中创建多个 YAML 对象
  8. $ cat <<EOF | kubectl create -f -
  9. apiVersion: v1
  10. kind: Pod
  11. metadata:
  12.   name: busybox-sleep
  13. spec:
  14.   containers:
  15.   - name: busybox
  16.     image: busybox
  17.     args:
  18.     - sleep
  19.     - "1000000"
  20. ---
  21. apiVersion: v1
  22. kind: Pod
  23. metadata:
  24.   name: busybox-sleep-less
  25. spec:
  26.   containers:
  27.   - name: busybox
  28.     image: busybox
  29.     args:
  30.     - sleep
  31.     - "1000"
  32. EOF
  33. # 创建包含几个 key 的 Secret
  34. $ cat <<EOF | kubectl create -f -
  35. apiVersion: v1
  36. kind: Secret
  37. metadata:
  38.   name: mysecret
  39. type: Opaque
  40. data:
  41.   password: $(echo "s33msi4" | base64)
  42.   username: $(echo "jane" | base64)
  43. EOF
复制代码
表现和查找资源

  1. # Get commands with basic output
  2. $ kubectl get services                          # 列出所有 namespace 中的所有 service
  3. $ kubectl get pods --all-namespaces             # 列出所有 namespace 中的所有 pod
  4. $ kubectl get pods -o wide                      # 列出所有 pod 并显示详细信息
  5. $ kubectl get deployment my-dep                 # 列出指定 deployment
  6. $ kubectl get pods --include-uninitialized      # 列出该 namespace 中的所有 pod 包括未初始化的
  7. # 使用详细输出来描述命令
  8. $ kubectl describe nodes my-node
  9. $ kubectl describe pods my-pod
  10. $ kubectl get services --sort-by=.metadata.name # List Services Sorted by Name
  11. # 根据重启次数排序列出 pod
  12. $ kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'
  13. # 获取所有具有 app=cassandra 的 pod 中的 version 标签
  14. $ kubectl get pods --selector=app=cassandra rc -o \
  15.   jsonpath='{.items[*].metadata.labels.version}'
  16. # 获取所有节点的 ExternalIP
  17. $ kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'
  18. # 列出属于某个 PC 的 Pod 的名字
  19. # “jq”命令用于转换复杂的 jsonpath,参考 https://stedolan.github.io/jq/
  20. $ sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}
  21. $ echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name})
  22. # 查看哪些节点已就绪
  23. $ JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
  24. && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"
  25. # 列出当前 Pod 中使用的 Secret
  26. $ kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq
复制代码
更新资源

  1. $ kubectl rolling-update frontend-v1 -f frontend-v2.json           # 滚动更新 pod frontend-v1
  2. $ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2  # 更新资源名称并更新镜像
  3. $ kubectl rolling-update frontend --image=image:v2                 # 更新 frontend pod 中的镜像
  4. $ kubectl rolling-update frontend-v1 frontend-v2 --rollback        # 退出已存在的进行中的滚动更新
  5. $ cat pod.json | kubectl replace -f -                              # 基于 stdin 输入的 JSON 替换 pod
  6. # 强制替换,删除后重新创建资源。会导致服务中断。
  7. $ kubectl replace --force -f ./pod.json
  8. # 为 nginx RC 创建服务,启用本地 80 端口连接到容器上的 8000 端口
  9. $ kubectl expose rc nginx --port=80 --target-port=8000
  10. # 更新单容器 pod 的镜像版本(tag)到 v4
  11. $ kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -
  12. $ kubectl label pods my-pod new-label=awesome                      # 添加标签
  13. $ kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq       # 添加注解
  14. $ kubectl autoscale deployment foo --min=2 --max=10                # 自动扩展 deployment “foo”
复制代码
修补资源

  1. $ kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' # 部分更新节点
  2. # 更新容器镜像; spec.containers[*].name 是必须的,因为这是合并的关键字
  3. $ kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'
  4. # 使用具有位置数组的 json 补丁更新容器镜像
  5. $ kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'
  6. # 使用具有位置数组的 json 补丁禁用 deployment 的 livenessProbe
  7. $ kubectl patch deployment valid-deployment  --type json   -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]'
复制代码
编辑资源

  1. $ kubectl edit svc/docker-registry                      # 编辑名为 docker-registry 的 service
  2. $ KUBE_EDITOR="nano" kubectl edit svc/docker-registry   # 使用其它编辑器
复制代码
scale资源

  1. $ kubectl scale --replicas=3 rs/foo                                 # Scale a replicaset named 'foo' to 3
  2. $ kubectl scale --replicas=3 -f foo.yaml                            # Scale a resource specified in "foo.yaml" to 3
  3. $ kubectl scale --current-replicas=2 --replicas=3 deployment/mysql  # If the deployment named mysql's current size is 2, scale mysql to 3
  4. $ kubectl scale --replicas=5 rc/foo rc/bar rc/baz                   # Scale multiple replication controllers
复制代码
删除资源

  1. $ kubectl scale --replicas=3 rs/foo                                 # Scale a replicaset named 'foo' to 3
  2. $ kubectl scale --replicas=3 -f foo.yaml                            # Scale a resource specified in "foo.yaml" to 3
  3. $ kubectl scale --current-replicas=2 --replicas=3 deployment/mysql  # If the deployment named mysql's current size is 2, scale mysql to 3
  4. $ kubectl scale --replicas=5 rc/foo rc/bar rc/baz                   # Scale multiple replication controllers
复制代码
1.2.4 Pod与集群

与运行的Pod交互

  1. $ kubectl logs my-pod                                 # dump 输出 pod 的日志(stdout)
  2. $ kubectl logs my-pod -c my-container                 # dump 输出 pod 中容器的日志(stdout,pod 中有多个容器的情况下使用)
  3. $ kubectl logs -f my-pod                              # 流式输出 pod 的日志(stdout)
  4. $ kubectl logs -f my-pod -c my-container              # 流式输出 pod 中容器的日志(stdout,pod 中有多个容器的情况下使用)
  5. $ kubectl run -i --tty busybox --image=busybox -- sh  # 交互式 shell 的方式运行 pod
  6. $ kubectl attach my-pod -i                            # 连接到运行中的容器
  7. $ kubectl port-forward my-pod 5000:6000               # 转发 pod 中的 6000 端口到本地的 5000 端口
  8. $ kubectl exec my-pod -- ls /                         # 在已存在的容器中执行命令(只有一个容器的情况下)
  9. $ kubectl exec my-pod -c my-container -- ls /         # 在已存在的容器中执行命令(pod 中有多个容器的情况下)
  10. $ kubectl top pod POD_NAME --containers               # 显示指定 pod 和容器的指标度量
复制代码
与节点和集群交互

  1. $ kubectl cordon my-node                                                # 标记 my-node 不可调度
  2. $ kubectl drain my-node                                                 # 清空 my-node 以待维护
  3. $ kubectl uncordon my-node                                              # 标记 my-node 可调度
  4. $ kubectl top node my-node                                              # 显示 my-node 的指标度量
  5. $ kubectl cluster-info                                                  # 显示 master 和服务的地址
  6. $ kubectl cluster-info dump                                             # 将当前集群状态输出到 stdout                                    
  7. $ kubectl cluster-info dump --output-directory=/path/to/cluster-state   # 将当前集群状态输出到 /path/to/cluster-state
  8. # 如果该键和影响的污点(taint)已存在,则使用指定的值替换
  9. $ kubectl taint nodes foo dedicated=special-user:NoSchedule
复制代码
1.2.5 资源类型与别名

资源类型缩写别名clusterscomponentstatusescsconfigmapscmdaemonsetsdsdeploymentsdeployendpointsepeventevhorizontalpodautoscalershpaingressesingjobslimitrangeslimitsnamespacesnsnetworkpoliciesnodesnostatefulsetspersistentvolumeclaimspvcpersistentvolumespvpodspopodsecuritypoliciespsppodtemplatesreplicasetsrsreplicationcontrollersrcresourcequotasquotacronjobsecretsserviceaccountsaservicessvcstorageclassesthirdpartyresources 1.2.6 格式化输出



  • 输出json格式:-o json
  • 仅打印资源名称:-o name
  • 以纯文本格式输出全部信息:-o wide
  • 输出yaml格式:-o yaml
1.3 API概述

官网文档:https://kubernetes.io/zh-cn/docs/reference/using-api/
REST API 是 Kubernetes 体系的重要部分,组件之间的全部操作和通讯均由 API Server 处理惩罚的 REST AP I调用,大多数环境下, API 定义和实现都符合标准的 HTTP REST 格式,可以通过 kubectl 下令管理工具或其他下令行工具来执行。
1.3.1 类型

Alpha



  • 包罗 alpha 名称的版本(比方v1alpha1)。
  • 该软件可能包罗错误。启用一个功能可能会导致 bug。默认环境下,功能可能会被禁用。
  • 随时可能会丢弃对该功能的支持,恕不另行关照。
  • API 可能在以后的软件版本中以不兼容的方式更改,恕不另行关照。
  • 该软件发起仅在短期测试集群中使用,由于错误的风险增长和缺乏恒久支持。
Beta



  • 包罗 beta 名称的版本(比方 v2beta3 )。
  • 该软件经过很好的测试。启用功能被认为是安全的。默认环境下功能是开启的。
  • 细节可能会改变,但功能在后续版本不会被删除
  • 对象的模式或语义在随后的 beta 版本或 Stable 版本中可能以不兼容的方式发生变革。如果这种环境发生时,官方会提供迁徙操作指南。这可能需要删除、编辑和重新创建API对象。
  • 该版本在后续可能会更改一些不兼容地方,以是发起用于非关键业务,如果你有多个可以独立升级的集群,你也可以放宽此限制。
  • 各人使用过的 Beta 版本后,可以多给社区反馈,如果此版本在后续更新后将不会有太大变革。
Stable



  • 该版本名称命名方式:vX 这里 X 是一个整数。
  • Stable 版本的功能特性,将出现在后续发布的软件版本中。
1.3.2 访问控制

认证

授权

1.3.3 废弃api说明

https://kubernetes.io/zh-cn/docs/reference/using-api/deprecation-guide/
二、深入pod

2.1 Pod设置文件

  1. apiVersion: v1 # api 文档版本
  2. kind: Pod  # 资源对象类型,也可以配置为像Deployment、StatefulSet这一类的对象
  3. metadata: # Pod 相关的元数据,用于描述 Pod 的数据
  4.   name: nginx-demo # Pod 的名称
  5.   labels: # 定义 Pod 的标签
  6.     type: app # 自定义 label 标签,名字为 type,值为 app
  7.     test: 1.0.0 # 自定义 label 标签,描述 Pod 版本号
  8.   namespace: 'default' # 命名空间的配置
  9. spec: # 期望 Pod 按照这里面的描述进行创建
  10.   containers: # 对于 Pod 中的容器描述
  11.   - name: nginx # 容器的名称
  12.     image: nginx:1.7.9 # 指定容器的镜像
  13.     imagePullPolicy: IfNotPresent # 镜像拉取策略,指定如果本地有就用本地的,如果没有就拉取远程的
  14.     command: # 指定容器启动时执行的命令
  15.     - nginx
  16.     - -g
  17.     - 'daemon off;' # nginx -g 'daemon off;'
  18.     workingDir: /usr/share/nginx/html # 定义容器启动后的工作目录
  19.     ports:
  20.     - name: http # 端口名称
  21.       containerPort: 80 # 描述容器内要暴露什么端口
  22.       protocol: TCP # 描述该端口是基于哪种协议通信的
  23.     - env: # 环境变量
  24.       name: JVM_OPTS # 环境变量名称
  25.       value: '-Xms128m -Xmx128m' # 环境变量的值
  26.     reousrces:
  27.       requests: # 最少需要多少资源
  28.         cpu: 100m # 限制 cpu 最少使用 0.1 个核心
  29.         memory: 128Mi # 限制内存最少使用 128兆
  30.       limits: # 最多可以用多少资源
  31.         cpu: 200m # 限制 cpu 最多使用 0.2 个核心
  32.         memory: 256Mi # 限制 最多使用 256兆
  33.   restartPolicy: OnFailure # 重启策略,只有失败的情况才会重启
复制代码
2.2 探针

2.2.1 类型

StartupProbe

k8s 1.16 版本新增的探针,用于判断应用程序是否已经启动了。
当设置了 startupProbe 后,会先禁用其他探针,直到 startupProbe 成功后,其他探针才会继续。
作用:由于有时候不能正确预估应用一定是多长时间启动成功,因此设置另外两种方式不方便设置初始化时长来检测,而设置了 statupProbe 后,只有在应用启动成功了,才会执行另外两种探针,可以更加方便的结合使用另外两种探针使用。
  1. startupProbe: # 应用启动探针配置
  2.   httpGet: # 探测方式,基于 http 请求探测
  3.     path: /api/startup # http请求路径
  4.     port: 80 # 请求端口
复制代码
LivenessProbe

用于探测容器中的应用是否运行,如果探测失败,kubelet 会根据设置的重启计谋进行重启,若没有设置,默认就认为容器启动成功,不会执行重启计谋。
  1. livenessProbe:
  2.   failureThreshold: 5
  3.   httpGet:
  4.     path: /health
  5.     port: 8080
  6.     scheme: HTTP
  7.   initialDelaySeconds: 60
  8.   periodSeconds: 10
  9.   successThreshold: 1
  10.   timeoutSeconds: 5
复制代码
ReadinessProbe

用于探测容器内的程序是否健康,它的返回值如果返回 success,那么就认为该容器已经完全启动,而且该容器是可以接收外部流量的。
  1. readinessProbe:
  2.   failureThreshold: 3 # 失败多少次才算真正失败
  3.   httpGet:
  4.     path: /ready
  5.     port: 8181
  6.     scheme: HTTP
  7.   periodSeconds: 10 # 间隔时间
  8.   successThreshold: 1 # 多少次监测成功算成功
  9.   timeoutSeconds: 1 # 请求的超时时间
复制代码
2.2.2探测方式

ExecAction

在容器内部执行一个下令,如果返回值为 0,则任务容器时健康的。
  1. livenessProbe:
  2.   exec:
  3.     command:
  4.       - cat
  5.       - /health
复制代码
TCPSocketAction

通过 tcp 毗连监测容器内端口是否开放,如果开放则证明该容器健康
  1. livenessProbe:
  2.   tcpSocket:
  3.     port: 80
复制代码
HTTPGetAction

生产环境用的较多的方式,发送 HTTP 哀求到容器内的应用程序,如果接口返回的状态码在 200~400 之间,则认为容器健康。
  1. livenessProbe:
  2.   failureThreshold: 5
  3.   httpGet:
  4.     path: /health
  5.     port: 8080
  6.     scheme: HTTP
  7.     httpHeaders:
  8.       - name: xxx
  9.         value: xxx
复制代码
2.2.3 参数设置

  1. initialDelaySeconds: 60 # 初始化时间
  2. timeoutSeconds: 2 # 超时时间
  3. periodSeconds: 5 # 监测间隔时间
  4. successThreshold: 1 # 检查 1 次成功就表示成功
  5. failureThreshold: 2 # 监测失败 2 次就表示失败
复制代码
2.3 生命周期


  1. lifecycle:
  2.   postStart: # 容创建完成后执行的动作,不能保证该操作一定在容器的 command 之前执行,一般不使用
  3.     exec: # 可以是 exec / httpGet / tcpSocket
  4.       command:
  5.         - sh
  6.         - -c
  7.         - 'mkdir /data'
  8.   preStop: # 在容器停止前执行的动作
  9.     httpGet: # 发送一个 http 请求
  10.       path: /
  11.       port: 80
  12.     exec: # 执行一个命令
  13.       command:
  14.         - sh
  15.         - -c
  16.         - sleep 9
复制代码
2.3.1 Pod退出流程

删除操作


  • Endpoint删除pod的ip地址
  • Pod变成Terminating状态
    变为删除中的状态后,会给 pod 一个脱期期,让 pod 去执行一些清算或销毁操作。
    1. 配置参数:
    2. # 作用与 pod 中的所有容器
    3. terminationGracePeriodSeconds: 30
    4. containers:
    5.   - xxx
    复制代码
  • 执行perStop的指令
2.3.2 PreStop的应用

如果应用销毁操作耗时需要比较长,可以在 preStop 按照如下方式进行设置
  1. preStop:
  2.   exec:
  3.     command:
  4.       - sh
  5.       - -c
  6.       - 'sleep 20; kill pgrep java'
复制代码
但是需要注意,由于 k8s 默认给 pod 的停止脱期时间为 30s,如果我们停止操作会凌驾 30s 时,不要光设置 sleep 50,还要将 terminationGracePeriodSeconds: 30 也更新成更长的时间,否则 k8s 最多只会在这个时间的底子上再脱期几秒,不会真正等待 50s
注册中心下线
数据清算
数据销毁
三、资源调理

3.1 Label和Slelctor

3.1.1 标签(Label)

设置文件

在各类资源的 metadata.labels 中进行设置
kubectl

临时创建label:
  1. kubectl label po <资源名称> app=hello -n namespace
复制代码
修改已经存在的标签:
  1. kubectl label po <资源名称> app=hello2 --overwrite
复制代码
检察label:
  1. # selector 按照 label 单值查找节点
  2. kubectl get po -A -l app=hello
  3. # 查看所有节点的 labels
  4. kubectl get po --show-labels
复制代码
3.1.2 选择器(Selector)

设置文件

在各对象的设置 spec.selector 或其他可以写 selector 的属性中编写
kubectl

  1. # 匹配单个值,查找 app=hello 的 pod
  2. kubectl get po -A -l app=hello
  3. # 匹配多个值
  4. kubectl get po -A -l 'k8s-app in (metrics-server, kubernetes-dashboard)'
  5. # 查找 version!=1 and app=nginx 的 pod 信息
  6. kubectl get po -l version!=1,app=nginx
  7. # 不等值 + 语句
  8. kubectl get po -A -l version!=1,'app in (busybox, nginx)'
复制代码
3.2 Deployment

3.2.1 功能

创建

  1. 创建一个 deployment
  2. kubectl create deploy nginx-deploy --image=nginx:1.7.9
  3. 或执行
  4. kubectl create -f xxx.yaml --record
  5. --record 会在 annotation 中记录当前命令创建或升级了资源,后续可以查看做过哪些变动操作。
  6. 将创建的 deployment 以 yaml 的格式输出
  7. kubectl get deploy nginx-deploy -o yaml
  8. 查看部署信息
  9. kubectl get deployments
  10. 查看 rs
  11. kubectl get rs
  12. 查看 pod 以及展示标签,可以看到是关联的那个 rs
  13. kubectl get pods --show-labels
复制代码
滚动更新

只有修改了 deployment 设置文件中的 template 中的属性后,才会触发更新操作
  1. 修改 nginx 版本号
  2. kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
  3. 或者通过 kubectl edit deployment/nginx-deployment 进行修改
  4. 查看滚动更新的过程
  5. kubectl rollout status deploy <deployment_name>
  6. 查看部署描述,最后展示发生的事件列表也可以看到滚动更新过程
  7. kubectl describe deploy <deployment_name>
  8. 通过 kubectl get deployments 获取部署信息,UP-TO-DATE 表示已经有多少副本达到了配置中要求的数目
  9. 通过 kubectl get rs 可以看到增加了一个新的 rs
  10. 通过 kubectl get pods 可以看到所有 pod 关联的 rs 变成了新的
复制代码
多个滚动更新并行
假设当前有 5 个 nginx:1.7.9 版本,你想将版本更新为 1.9.1,当更新成功第三个以后,你立刻又将盼望更新的版本改为 1.9.2,那么此时会立马删除之前的三个,而且立马开启更新 1.9.2 的任务
回滚

有时候你可能想回退一个Deployment,比方,当Deployment不稳定时,比如一直crash looping。
默认环境下,kubernetes会在体系中保存前两次的Deployment的rollout汗青记载,以便你可以随时会退(你可以修改revision history limit来更改保存的revision数)。
  1. 案例:
  2. 更新 deployment 时参数不小心写错,如 nginx:1.9.1 写成了 nginx:1.91
  3. kubectl set image deployment/nginx-deploy nginx=nginx:1.91
  4. 监控滚动升级状态,由于镜像名称错误,下载镜像失败,因此更新过程会卡住
  5. kubectl rollout status deployments nginx-deploy
  6. 结束监听后,获取 rs 信息,我们可以看到新增的 rs 副本数是 2 个
  7. kubectl get rs
  8. 通过 kubectl get pods 获取 pods 信息,我们可以看到关联到新的 rs 的 pod,状态处于 ImagePullBackOff 状态
  9. 为了修复这个问题,我们需要找到需要回退的 revision 进行回退
  10. 通过 kubectl rollout history deployment/nginx-deploy 可以获取 revison 的列表
  11. 通过 kubectl rollout history deployment/nginx-deploy --revision=2 可以查看详细信息
  12. 确认要回退的版本后,可以通过 kubectl rollout undo deployment/nginx-deploy 可以回退到上一个版本
  13. 也可以回退到指定的 revision
  14. kubectl rollout undo deployment/nginx-deploy --to-revision=2
  15. 再次通过 kubectl get deployment 和 kubectl describe deployment 可以看到,我们的版本已经回退到对应的 revison 上了
  16. 可以通过设置 .spec.revisonHistoryLimit 来指定 deployment 保留多少 revison,如果设置为 0,则不允许 deployment 回退了。
复制代码
扩容缩容

通过 kube scale 下令可以进行主动扩容/缩容,以及通过 kube edit 编辑 replcas 也可以实现扩容/缩容
扩容与缩容只是直接创建副本数,没有更新 pod template 因此不会创建新的 rs
停息与规复

  1. 由于每次对 pod template 中的信息发生修改后,都会触发更新 deployment 操作,那么此时如果频繁修改信息,就会产生多次更新,而实际上只需要执行最后一次更新即可,当出现此类情况时我们就可以暂停 deployment 的 rollout
  2. 通过 kubectl rollout pause deployment <name> 就可以实现暂停,直到你下次恢复后才会继续进行滚动更新
  3. 尝试对容器进行修改,然后查看是否发生更新操作了
  4. kubectl set image deploy <name> nginx=nginx:1.17.9
  5. kubectl get po
  6. 通过以上操作可以看到实际并没有发生修改,此时我们再次进行修改一些属性,如限制 nginx 容器的最大cpu为 0.2 核,最大内存为 128M,最小内存为 64M,最小 cpu 为 0.1 核
  7. kubectl set resources deploy <deploy_name> -c <container_name> --limits=cpu=200m,memory=128Mi --requests=cpu100m,memory=64Mi
  8. 通过格式化输出 kubectl get deploy <name> -oyaml,可以看到配置确实发生了修改,再通过 kubectl get po 可以看到 pod 没有被更新
  9. 那么此时我们再恢复 rollout,通过命令 kubectl rollout deploy <name>
  10. 恢复后,我们再次查看 rs 和 po 信息,我们可以看到就开始进行滚动更新操作了
  11. kubectl get rs
  12. kubectl get po
复制代码
3.2.2 设置文件

  1. apiVersion: apps/v1 # deployment api 版本
  2. kind: Deployment # 资源类型为 deployment
  3. metadata: # 元信息
  4.   labels: # 标签
  5.     app: nginx-deploy # 具体的 key: value 配置形式
  6.   name: nginx-deploy # deployment 的名字
  7.   namespace: default # 所在的命名空间
  8. spec:
  9.   replicas: 1 # 期望副本数
  10.   revisionHistoryLimit: 10 # 进行滚动更新后,保留的历史版本数
  11.   selector: # 选择器,用于找到匹配的 RS
  12.     matchLabels: # 按照标签匹配
  13.       app: nginx-deploy # 匹配的标签key/value
  14.   strategy: # 更新策略
  15.     rollingUpdate: # 滚动更新配置
  16.       maxSurge: 25% # 进行滚动更新时,更新的个数最多可以超过期望副本数的个数/比例
  17.       maxUnavailable: 25% # 进行滚动更新时,最大不可用比例更新比例,表示在所有副本数中,最多可以有多少个不更新成功
  18.     type: RollingUpdate # 更新类型,采用滚动更新
  19.   template: # pod 模板
  20.     metadata: # pod 的元信息
  21.       labels: # pod 的标签
  22.         app: nginx-deploy
  23.     spec: # pod 期望信息
  24.       containers: # pod 的容器
  25.       - image: nginx:1.7.9 # 镜像
  26.         imagePullPolicy: IfNotPresent # 拉取策略
  27.         name: nginx # 容器名称
  28.       restartPolicy: Always # 重启策略
  29.       terminationGracePeriodSeconds: 30 # 删除操作最多宽限多长时间
复制代码
3.3 StatefulSet

3.3.1 功能

创建

  1. kubectl create -f web.yaml
  2. # 查看 service 和 statefulset => sts
  3. kubectl get service nginx
  4. kubectl get statefulset web
  5. # 查看 PVC 信息
  6. kubectl get pvc
  7. # 查看创建的 pod,这些 pod 是有序的
  8. kubectl get pods -l app=nginx
  9. # 查看这些 pod 的 dns
  10. # 运行一个 pod,基础镜像为 busybox 工具包,利用里面的 nslookup 可以看到 dns 信息
  11. kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
  12. nslookup web-0.nginx
复制代码
扩容缩容

  1. # 扩容缩容
  2. $ kubectl scale statefulset web --replicas=5
  3. # 扩容缩容
  4. $ kubectl patch statefulset web -p '{"spec":{"replicas":3}}'
复制代码
镜像更新

  1. # 镜像更新(目前还不支持直接更新 image,需要 patch 来间接实现)
  2. kubectl patch sts web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:1.9.1"}]'
复制代码
RollingUpdate

StatefulSet 也可以采用滚动更新计谋,同样是修改 pod template 属性后会触发更新,但是由于 pod 是有序的,在 StatefulSet 中更新时是基于 pod 的顺序倒序更新的
灰度发布

使用滚动更新中的 partition 属性,可以实现浅易的灰度发布的结果
比方我们有 5 个 pod,如果当前 partition 设置为 3,那么此时滚动更新时,只会更新那些 序号 >= 3 的 pod
使用该机制,我们可以通过控制 partition 的值,来决定只更新其中一部分 pod,确认没有问题后再主键增大更新的 pod 数量,最终实现全部 pod 更新
OnDelete

只有在 pod 被删除时会进行更新操作
删除

  1. # 删除 StatefulSet 和 Headless Service
  2. # 级联删除:删除 statefulset 时会同时删除 pods
  3. kubectl delete statefulset web
  4. # 非级联删除:删除 statefulset 时不会删除 pods,删除 sts 后,pods 就没人管了,此时再删除 pod 不会重建的
  5. kubectl deelte sts web --cascade=false
  6. # 删除 service
  7. kubectl delete service nginx
复制代码
删除pvc

  1. # StatefulSet删除后PVC还会保留着,数据不再使用的话也需要删除
  2. $ kubectl delete pvc www-web-0 www-web-1
复制代码
3.3.2 设置文件

  1. ---
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5.   name: nginx
  6.   labels:
  7.     app: nginx
  8. spec:
  9.   ports:
  10.   - port: 80
  11.     name: web
  12.   clusterIP: None
  13.   selector:
  14.     app: nginx
  15. ---
  16. apiVersion: apps/v1
  17. kind: StatefulSet # StatefulSet 类型的资源
  18. metadata:
  19.   name: web # StatefulSet 对象的名字
  20. spec:
  21.   serviceName: "nginx" # 使用哪个 service 来管理 dns
  22.   replicas: 2
  23.   selector:
  24.     matchLabels:
  25.       app:nginx
  26.   template:
  27.     metadata:
  28.       labels:
  29.         app: nginx
  30.     spec:
  31.       containers:
  32.       - name: nginx
  33.         image: nginx:1.7.9
  34.         ports: # 容器内部要暴露的端口
  35.         - containerPort: 80 # 具体暴露的端口号
  36.           name: web # 该端口配置的名字
  37.         volumeMounts: # 加载数据卷
  38.         - name: www # 指定加载哪个数据卷
  39.           mountPath: /usr/share/nginx/html # 加载到容器的哪个目录
  40.   volumeClaimTemplates: # 数据卷模板
  41.   - metadata: # 数据卷描述
  42.       name: www # 数据卷的名称
  43.       annotations: # 数据卷的注解
  44.         volume.alpha.kubernetes.io/storage-class: anything
  45.     spec: # 数据卷的规约
  46.       accessModes: [ "ReadWriteOnce" ] # 访问模式
  47.       resources:
  48.         requests:
  49.           storage: 1Gi
复制代码
3.4 DaemonSet

3.4.1 设置文件

  1. apiVersion: apps/v1
  2. kind: DaemonSet # 创建DaemonSet 资源
  3. metadata:
  4.   name: fluentd # 名字
  5. spec:
  6.   template:
  7.     metadata:
  8.       labels:
  9.         app: logging
  10.         id: fluentd
  11.       name: fluentd
  12.     spec:
  13.       containers:
  14.       - name: fluentd-es
  15.         image: agilestacks/fluentd-elasticsearch:v1.3.0
  16.         env: # 环境变量的key
  17.          - name: FLUENTD_ARGS # 环境变量的 key
  18.            value: -qq # 环境变量的value
  19.         volumeMounts: #加载数据卷,避免数据丢失
  20.          - name: containers #数据卷的名字
  21.            mountPath: /var/lib/docker/containers # 将数据卷挂载到容器内的哪个目录
  22.          - name: varlog
  23.            mountPath: /varlog
  24.       volumes: # 定义数据卷
  25.          - hostPath: #数据卷类型,主机路径的模式,也就是与node共享目录
  26.              path: /var/lib/docker/containers # node中的共享目录
  27.            name: containers 定义的数据卷的名称
  28.          - hostPath:
  29.              path: /var/log
  30.            name: varlog
复制代码
3.4.2 指定Node节点

DaemonSet 会忽略 Node 的 unschedulable 状态,有两种方式来指定 Pod 只运行在指定的 Node 节点上:


  • nodeSelector:只调理到匹配指定 label 的 Node 上
    1. 先为 Node 打上标签
    2. kubectl label nodes k8s-node1 svc_type=microsvc
    3. 然后再 daemonset 配置中设置 nodeSelector
    4. spec:
    5.   template:
    6.     spec:
    7.       nodeSelector:
    8.         svc_type: microsvc
    复制代码
  • nodeAffinity:功能更丰富的 Node 选择器,比如支持集合操作
    1. nodeAffinity 目前支持两种:requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution,分别代表必须满足条件和优选条件。
    2. 比如下面的例子代表调度到包含标签 wolfcode.cn/framework-name 并且值为 spring 或 springboot 的 Node 上,并且优选还带有标签 another-node-label-key=another-node-label-value 的Node。
    3. apiVersion: v1
    4. kind: Pod
    5. metadata:
    6.   name: with-node-affinity
    7. spec:
    8.   affinity:
    9.     nodeAffinity:
    10.       requiredDuringSchedulingIgnoredDuringExecution:
    11.         nodeSelectorTerms:
    12.         - matchExpressions:
    13.           - key: wolfcode.cn/framework-name
    14.             operator: In
    15.             values:
    16.             - spring
    17.             - springboot
    18.       preferredDuringSchedulingIgnoredDuringExecution:
    19.       - weight: 1
    20.         preference:
    21.           matchExpressions:
    22.           - key: another-node-label-key
    23.             operator: In
    24.             values:
    25.             - another-node-label-value
    26.   containers:
    27.   - name: with-node-affinity
    28.     image: pauseyyf/pause
    复制代码
  • podAffinity:调理到满足条件的 Pod 所在的 Node 上
    1. podAffinity 基于 Pod 的标签来选择 Node,仅调度到满足条件Pod 所在的 Node 上,支持 podAffinity 和 podAntiAffinity。这个功能比较绕,以下面的例子为例:
    2.     如果一个 “Node 所在空间中包含至少一个带有 auth=oauth2 标签且运行中的 Pod”,那么可以调度到该 Node
    3.     不调度到 “包含至少一个带有 auth=jwt 标签且运行中 Pod”的 Node 上
    4. apiVersion: v1
    5. kind: Pod
    6. metadata:
    7.   name: with-pod-affinity
    8. spec:
    9.   affinity:
    10.     podAffinity:
    11.       requiredDuringSchedulingIgnoredDuringExecution:
    12.       - labelSelector:
    13.           matchExpressions:
    14.           - key: auth
    15.             operator: In
    16.             values:
    17.             - oauth2
    18.         topologyKey: failure-domain.beta.kubernetes.io/zone
    19.     podAntiAffinity:
    20.       preferredDuringSchedulingIgnoredDuringExecution:
    21.       - weight: 100
    22.         podAffinityTerm:
    23.           labelSelector:
    24.             matchExpressions:
    25.             - key: auth
    26.               operator: In
    27.               values:
    28.               - jwt
    29.           topologyKey: kubernetes.io/hostname
    30.   containers:
    31.   - name: with-pod-affinity
    32.     image: pauseyyf/pause
    复制代码
3.4.3 滚动更新

不发起使用 RollingUpdate,发起使用 OnDelete 模式,这样避免频仍更新 ds
3.5 HPA主动扩/缩容

通过观察 pod 的 cpu、内存使用率或自定义 metrics 指标进行主动的扩容或缩容 pod 的数量。
通常用于 Deployment,不适用于无法扩/缩容的对象,如 DaemonSet
控制管理器每隔30s(可以通过–horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用环境
3.5.1 开启指标服务

  1. # 下载 metrics-server 组件配置文件
  2. wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml -O metrics-server-components.yaml
  3. # 修改镜像地址为国内的地址
  4. sed -i 's/k8s.gcr.io\/metrics-server/registry.cn-hangzhou.aliyuncs.com\/google_containers/g' metrics-server-components.yaml
  5. # 修改容器的 tls 配置,不验证 tls,在 containers 的 args 参数中增加 --kubelet-insecure-tls 参数
  6. # 安装组件
  7. kubectl apply -f metrics-server-components.yaml
  8. # 查看 pod 状态
  9. kubectl get pods --all-namespaces | grep metrics
复制代码
3.5.2 cpu、内存指标监控

  1. 实现 cpu 或内存的监控,首先有个前提条件是该对象必须配置了 resources.requests.cpu 或 resources.requests.memory 才可以,可以配置当 cpu/memory 达到上述配置的百分比后进行扩容或缩容
  2. 创建一个 HPA:
  3. 先准备一个好一个有做资源限制的 deployment
  4. 执行命令 kubectl autoscale deploy nginx-deploy --cpu-percent=20 --min=2 --max=5
  5. 通过 kubectl get hpa 可以获取 HPA 信息
  6. 测试:找到对应服务的 service,编写循环测试脚本提升内存与 cpu 负载
  7. while true; do wget -q -O- http://<ip:port> > /dev/null ; done
  8. 可以通过多台机器执行上述命令,增加负载,当超过负载后可以查看 pods 的扩容情况 kubectl get pods
  9. 查看 pods 资源使用情况
  10. kubectl top pods
  11. 扩容测试完成后,再关闭循环执行的指令,让 cpu 占用率降下来,然后过 5 分钟后查看自动缩容情况
复制代码
3.5.3 自定义metrics



  • 控制管理器开启–horizontal-pod-autoscaler-use-rest-clients
  • 控制管理器的–apiserver指向API Server Aggregator
  • 在API Server Aggregator中注册自定义的metrics API
四、服务发布

4.1 Service

负责东西流量(同层级/内部服务网络通讯)的通讯
4.1.1 Service的定义

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4.   name: nginx-svc
  5.   labels:
  6.     app: nginx-svc
  7. spec:
  8.   type: NodePort # NodePort可外部通过节点IP访问,ClusterIP仅内部访问
  9.   ports:
  10.   - name: http # service 端口配置的名称
  11.     protocol: TCP # 端口绑定的协议,支持 TCP、UDP、SCTP,默认为 TCP
  12.     port: 80 # service 自己的端口
  13.     targetPort: 9527 # 目标 pod 的端口
  14.     nodePort: 31000 # type为NodePort时可配置,不指定会在30000-32767里随机一个端口
  15.   - name: https
  16.     port: 443
  17.     protocol: TCP
  18.     targetPort: 443
  19.   selector: # 选中当前 service 匹配哪些 pod,对哪些 pod 的东西流量进行代理
  20.     app: nginx
复制代码
下令操作

  1. # 创建 service
  2. kubectl create -f nginx-svc.yaml
  3. # 查看 service 信息,通过 service 的 cluster ip 进行访问
  4. kubectl get svc
  5. # 查看 pod 信息,通过 pod 的 ip 进行访问
  6. kubectl get po -o wide
  7. # 创建其他 pod 通过 service name 进行访问(推荐)
  8. kubectl exec -it busybox -- sh
  9. curl http://nginx-svc
  10. # 默认在当前 namespace 中访问,如果需要跨 namespace 访问 pod,则在 service name 后面加上 .<namespace> 即可
  11. curl http://nginx-svc.default
复制代码
Endpoint

4.1.2署理k8s外部服务

  1. 实现方式:
  2. 编写 service 配置文件时,不指定 selector 属性
  3. 自己创建 endpoint
  4. endpoint 配置:
  5. apiVersion: v1
  6. kind: Endpoints
  7. metadata:
  8.   labels:
  9.     app: nginx-svc-external # 与 service 一致
  10.   name: nginx-svc-external # 与 service 一致
  11.   namespace: default # 与 service 一致
  12. subsets:
  13. - addresses:
  14.   - ip: <target ip> # 目标 ip 地址
  15.   ports: # 与 service 一致
  16.   - name: http
  17.     port: 80
  18.     protocol: TCP
复制代码


  • 各环境访问名称同一
  • 访问k8s集群外的其他服务
  • 项目迁徙
4.1.3反向署理外部域名

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4.   labels:
  5.     app: wolfcode-external-domain
  6.   name: wolfcode-external-domain
  7. spec:
  8.   type: ExternalName
  9.   externalName: www.wolfcode.cn
复制代码
4.1.4 常用类型

ClusterIP

只能在集群内部使用,不设置类型的话默认就是 ClusterIP
ExternalName

返回定义的 CNAME 别名,可以设置为域名
NodePort

会在全部安装了 kube-proxy 的节点都绑定一个端口,此端口可以署理至对应的 Pod,集群外部可以使用恣意节点 ip + NodePort 的端标语访问到集群中对应 Pod 中的服务。
当类型设置为 NodePort 后,可以在 ports 设置中增长 nodePort 设置指定端口,需要在下方的端口范围内,如果不指定会随机指定端口
端口范围:30000~32767
端口范围设置在 /usr/lib/systemd/system/kube-apiserver.service 文件中
LoadBalancer

使用云服务商(阿里云、腾讯云等)提供的负载平衡器服务
4.2 Ingress

Ingress 各人可以明白为也是一种 LB 的抽象,它的实现也是支持 nginx、haproxy 等负载平衡服务的
4.2.1 安装ingress-nginx

https://kubernetes.github.io/ingress-nginx/deploy/#using-helm
  1. 1.添加ingress-nginx官方helm仓库
  2. helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
  3. helm repo update
  4. 2.查找所有的版本
  5. helm search repo ingress-nginx/ingress-nginx -l
  6. 3.下载
  7. helm fetch ingress-nginx/ingress-nginx --version 4.5.2
  8. 4.解压缩
  9. tar zxvf ingress-nginx-4.5.2.tgz
复制代码
  1. 进入ingress-nginx目录修改values.yaml参数配置
  2. 1.修改dnsPolicy的值为ClusterFirstWithHostNet
  3.     # By default, while using host network, name resolution uses the host's DNS. If you wish nginx-controller
  4.     # to keep resolving names inside the k8s network, use ClusterFirstWithHostNet.
  5.     #dnsPolicy: ClusterFirst
  6.     dnsPolicy: ClusterFirstWithHostNet
  7.    
  8. 2.修改hostNetwork的值为true
  9.     # -- Required for use with CNI based kubernetes installations (such as ones set up by kubeadm),
  10.     # since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920
  11.     # is merged
  12.     #hostNetwork: false
  13.     hostNetwork: true
  14.    
  15. 3.修改kind的值为DaemonSet
  16.     # -- Use a `DaemonSet` or `Deployment`
  17.     #kind: Deployment
  18.     kind: DaemonSet
  19.    
  20. 4.在nodeSelector下添加ingress: "true"  # 增加选择器,如果 node 上有 ingress=true 就部署
  21.     nodeSelector:
  22.         kubernetes.io/os: linux
  23.         ingress: "true"
  24.         
  25. 5.修改type的值为ClusterIP  # 将 service 中的 type 由 LoadBalancer 修改为 ClusterIP,如果服务器是云平台才用 LoadBalancer
  26.         ## Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/
  27.         ipFamilies:
  28.             - IPv4
  29.         ports:
  30.             http: 80
  31.             https: 443
  32.         targetPorts:
  33.             http: http
  34.             https: https
  35.         #type: LoadBalancer
  36.         type: ClusterIP
  37.         
  38. 6.修改enabled的值为false
  39.         ## Additional annotations to the admission webhooks.
  40.         ## These annotations will be added to the ValidatingWebhookConfiguration and
  41.         ## the Jobs Spec of the admission webhooks.
  42.         #enabled: true
  43.         enabled: false
复制代码
  1. 给node打标签
  2. kubectl label nodes k8s-node1 ingress=true
  3. 新建命令空间
  4. kubectl create namespace ingress-nginx
  5. 安装ingress-nginx
  6. cd ingress-nginx/
  7. helm install ingress-nginx -n ingress-nginx .
复制代码
4.2.2 基本使用

创建一个ingress

文档:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/
  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress # 资源类型为 Ingress
  3. metadata:
  4.   name: ingress-nginx-test
  5.   annotations:
  6.     kubernetes.io/ingress.class: "nginx"
  7.     nginx.ingress.kubernetes.io/rewrite-target: /
  8. spec:
  9.   rules: # ingress 规则配置,可以配置多个
  10.   - host: www.xiaoyu.com # 域名配置,可以使用通配符 *
  11.     http:
  12.       paths: # 相当于 nginx 的 location 配置,可以配置多个
  13.       - pathType: Prefix # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,具体匹配规则以 IngressClass 中的规则为准。Exact:精确匹配,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配
  14.         backend:
  15.           service:
  16.             name: nginx # 代理到哪个 service
  17.             port:
  18.               number: 80 # service 的端口
  19.         path: /api # 等价于 nginx 中的 location 的路径前缀匹配
复制代码
多域名设置

  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress # 资源类型为 Ingress
  3. metadata:
  4.   name: ingress-nginx-test
  5.   annotations:
  6.     kubernetes.io/ingress.class: "nginx"
  7.     nginx.ingress.kubernetes.io/rewrite-target: /
  8. spec:
  9.   rules: # ingress 规则配置,可以配置多个
  10.   - host: www.xiaoyu.com # 域名配置,可以使用通配符 *
  11.     http:
  12.       paths: # 相当于 nginx 的 location 配置,可以配置多个
  13.       - pathType: Prefix # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,具体匹配规则以 IngressClass 中的规则为准。Exact:精确匹配,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配
  14.         backend:
  15.           service:
  16.             name: nginx # 代理到哪个 service
  17.             port:
  18.               number: 80 # service 的端口
  19.         path: /api # 等价于 nginx 中的 location 的路径前缀匹配
  20.       - pathType: Exec # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,详细匹配规则以 IngressClass 中的规则为准。Exact:精确匹配>,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配        backend:          service:            name: nginx # 署理到哪个 service            port:              number: 80 # service 的端口        path: /  - host: api.xiaoyu.com # 域名设置,可以使用通配符 *    http:      paths: # 相当于 nginx 的 location 设置,可以设置多个      - pathType: Prefix # 路径类型,按照路径类型进行匹配 ImplementationSpecific 需要指定 IngressClass,详细匹配规则以 IngressClass 中的规则为准。Exact:精确匹配>,URL需要与path完全匹配上,且区分大小写的。Prefix:以 / 作为分隔符来进行前缀匹配        backend:          service:            name: nginx # 署理到哪个 service            port:              number: 80 # service 的端口        path: /
复制代码
五、设置与存储

5.1 设置管理

5.1.1 ConfigMap

创建
使用 kubectl create configmap -h 检察示例,构建 configmap 对象
使用ConfigMap
  1. 创建configmap:
  2. vim db.properties
  3. username=root
  4. password=admin
  5. vim redis.properties
  6. host: 127.0.0.1
  7. port: 6379
  8. kubectl create cm test-dir-config --from-file=./
  9. kubectl create configmap test-env-config --from-literal=JAVA_OPTS_TEST='-Xms512m -Xmx512m' --from-literal=APP_NAME='springboot-env-test'
  10. 编写配置文件:
  11. apiVersion: v1
  12. kind: Pod
  13. metadata:
  14.   name: test-cm-pod
  15. spec:
  16.   restartPolicy: Never
  17.   containers:
  18.   - name: env-test
  19.     image: alpine
  20.     command: ["bin/sh","-c","env;sleep 3600"]
  21.     imagePullPolicy: IfNotPresent
  22.     env:
  23.     - name: JAVA_VM_OPTS
  24.       valueFrom:
  25.         configMapKeyRef:
  26.           name: test-env-config # configMap的名字
  27.           key: JAVA_OPTS_TEST # 表示从 name 的 configMap 中获取名字为 key 的 value,将其赋值给本地环境变量 JAVA_OPTS_TEST
  28.     - name: APP
  29.       valueFrom:
  30.         configMapKeyRef:
  31.           name: test-env-config
  32.           key: APP_NAME
  33.     volumMounts: # 加载数据卷
  34.     - name: db-config # 表示加载volumes 属性中哪个数据卷
  35.       mountPath: "/usr/local/mysql/conf" # 想要将数据卷中的文件加载到哪个目录下
  36.       readOnly: true # 是否只读
  37.   volumes: # 数据卷挂载 configMap、secret
  38.   - name: db-config # 数据卷的名字,随意设置
  39.     configMap: # 数据卷类型为configMap
  40.       name: test-dir-config # configMap的名字,必须跟想要加载的configMap 相同
  41.       items: #对 configMap 中的 key 进行映射,如果不指定,默认会将 configMap中所有 key 全部转换为一个个同名的文件
  42.       - key: "db.properties" # configMap中的key
  43.         path: "db.properties" # 将该 key 的值转换为文件         
  44.          
  45. 创建pod:
  46. kubectl create -f test-cm-pod.yaml
  47. 测试查看打印的环境变量中是否有JAVA_VM_OPTS和APP:
  48. kubectl logs -f test-cm-pod
  49. 测试查看/usr/local/mysql/conf下是否有db.properties文件
  50. kubectl exec -it test-cm-pod -- sh
复制代码
5.1.2 加密数据设置Secret

与 ConfigMap 雷同,用于存储设置信息,但是主要用于存储敏感信息、需要加密的信息,Secret 可以提供数据加密、解密功能。
在创建 Secret 时,要注意如果要加密的字符中,包罗了有特殊字符,需要使用转义符转移,比方 $ 转移后为 $,也可以对特殊字符使用单引号形貌,这样就不需要转移比方 1$289*-! 转换为 ‘1$289*-!’
  1. kubectl create secret -h
  2. kubectl create secret docker-registry -h
  3. kubectl create secret docker-registry sec-test --docker-username=admin --docker-password=test --docker-email=test@test.com
  4. 编写配置文件
  5. apiVersion: v1
  6. kind: Pod
  7. metadata:
  8.   name: private-image-pull-pod
  9. spec:
  10.   imagePullSecrets: # 配置登录docker registry的secret
  11.   name: test-secret
  12.   containers:
  13.   - name: nginx
  14.     image: 192.168.112.110:8858/test/nginx:latest
  15.     command: ["bin/sh","-c","env;sleep 3600"]
  16.     imagePullPolicy: IfNotPresent
  17.     env:
  18.     - name: JAVA_VM_OPTS
  19.       valueFrom:
  20.         configMapKeyRef:
  21.           name: test-env-config # configMap的名字
  22.           key: JAVA_OPTS_TEST # 表示从 name 的 configMap 中获取名字为 key 的 value,将其赋值给本地环境变量 JAVA_OPTS_TEST
  23.     - name: APP
  24.       valueFrom:
  25.         configMapKeyRef:
  26.           name: test-env-config
  27.           key: APP_NAME
复制代码
5.1.3 SubPath的使用

使用 ConfigMap 或 Secret 挂载到目录的时候,会将容器中源目录给覆盖掉,此时我们可能只想覆盖目录中的某一个文件,但是这样的操作会覆盖整个文件,因此需要使用到 SubPath
设置方式:

  • 定义 volumes 时需要增长 items 属性,设置 key 和 path,且 path 的值不能从 / 开始
  • 在容器内的 volumeMounts 中增长 subPath 属性,该值与 volumes 中 items.path 的值相同
  1. kubectl create configmap nginx-conf-cm --from-file=./nginx.conf
  2. containers:
  3.   ......
  4.   volumeMounts: # 挂载数据卷
  5.   - mountPath: '/etc/nginx' # 挂载的路径
  6.     name: nginx-conf # 使用哪个 configmap 或 secret
  7.     subPath: etc/nginx/nginx.conf # 与 volumes.[0].items.path 相同
  8. volumes:
  9. - name: nginx-conf # 数据卷的名称
  10.   configMap: #数据卷类型为configmap
  11.     name: nginx-conf-cm # configMap 名字
  12.     items: # subPath 配置,要将configmap中的哪些数据挂载进来
  13.       key: nginx.conf # 指定要挂载哪个key
  14.       path: nginx.conf # 挂载后该key重命名为什么名字
复制代码
5.1.4 设置的热更新

我们通常会将项目的设置文件作为 configmap 然后挂载到 pod,那么如果更新 configmap 中的设置,会不会更新到 pod 中呢?
这得分成几种环境:
默认方式:会更新,更新周期是更新时间 + 缓存时间
subPath:不会更新
变量形式:如果 pod 中的一个变量是从 configmap 或 secret 中得到,同样也是不会更新的
对于 subPath 的方式,我们可以取消 subPath 的使用,将设置文件挂载到一个不存在的目录,避免目录的覆盖,然后再使用软毗连的形式,将该文件链接到目的位置
但是如果目的位置原本就有文件,可能无法创建软链接,此时可以基于前面讲过的 postStart 操作执行删除下令,将默认的吻技安删除即可
5.1.4.1 通过edit下令直接修改configmap

  1. kubectl edit cm test-dir-config
复制代码
5.1.4.2 通过replace替换

由于 configmap 我们创建通常都是基于文件创建,并不会编写 yaml 设置文件,因此修改时我们也是直接修改设置文件,而 replace 是没有 --from-file 参数的,因此无法实现基于源设置文件的替换,此时我们可以使用下方的下令实现
# 该下令的重点在于 --dry-run 参数,该参数的意思打印 yaml 文件,但不会将该文件发送给 apiserver,再结合 -oyaml 输出 yaml 文件就可以得到一个设置好但是没有发给 apiserver 的文件,然后再结合 replace 监听控制台输出得到 yaml 数据即可实现替换
  1. kubectl create cm --from-file=nginx.conf --dry-run -oaml | kubectl replace -f-
复制代码
5.1.5 不可变的Secret和ConfigMap

对于一些敏感服务的设置文件,在线上有时是不允许修改的,此时在设置 configmap 时可以设置  immutable: true来克制修改
  1. apiVersion: v1
  2. ...
  3. immutable: true
复制代码
5.2 持久化存储

5.2.1 Volumes

Hostpath

将节点上的文件或目录挂载到 Pod 上,此时该目录会变成持久化存储目录,即使 Pod 被删除后重启,也可以重新加载到该目录,该目录下的文件不会丢失
设置文件

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4.   name: test-volume-pod
  5. spec:
  6.   containers:
  7.   - image: nginx
  8.     name: nginx-volume
  9.     volumeMounts:
  10.     - mountPath: /test-pd # 挂载到容器的哪个目录
  11.       name: test-volume # 挂载哪个 volume
  12.   volumes:
  13.   - name: test-volume
  14.     hostPath: # 与主机共享目录,加载主机中的指定目录到容器中
  15.       path: /data # 节点中的目录
  16.       type: Directory # 检查类型,在挂载前对挂载目录做什么检查操作,有多种选项,默认为空字符串,不做任何检查
  17. 类型:
  18. 空字符串:默认类型,不做任何检查
  19. DirectoryOrCreate:如果给定的 path 不存在,就创建一个 755 的空目录
  20. Directory:这个目录必须存在
  21. FileOrCreate:如果给定的文件不存在,则创建一个空文件,权限为 644
  22. File:这个文件必须存在
  23. Socket:UNIX 套接字,必须存在
  24. CharDevice:字符设备,必须存在
  25. BlockDevice:块设备,必须存在
复制代码
EmptyDir

EmptyDir 主要用于一个 Pod 中不同的 Container 共享数据使用的,由于只是在 Pod 内部使用,因此与其他 volume 比较大的区别是,当 Pod 如果被删除了,那么 emptyDir 也会被删除。
存储介质可以是恣意类型,如 SSD、磁盘或网络存储。可以将 emptyDir.medium 设置为 Memory 让 k8s 使用 tmpfs(内存支持文件体系),速度比较快,但是重启 tmpfs 节点时,数据会被清除,且设置的大小管帐入到 Container 的内存限制中。
设置文件

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4.   name: empty-test-pod
  5. spec:
  6.   containers:
  7.   - image: nginx
  8.     name: nginx-emptydir1
  9.     volumeMounts:
  10.     - mountPath: /cache
  11.       name: cache-volume
  12.   - image: nginx
  13.     name: nginx-emptydir2
  14.     volumeMounts:
  15.     - mountPath: /share
  16.       name: cache-volume
  17.   volumes:
  18.   - name: cache-volume
  19.     emptyDir: {}
  20.    
  21. 测试
  22. kubectl exec -it empty-test-pod -c nginx-emptydir1 -- sh
复制代码
5.2.2 NFS挂载

nfs 卷能将 NFS (网络文件体系) 挂载到你的 Pod 中。 不像 emptyDir 那样会在删除 Pod 的同时也会被删除,nfs 卷的内容在删除 Pod 时会被保存,卷只是被卸载。 这意味着 nfs 卷可以被预先填充数据,而且这些数据可以在 Pod 之间共享。
安装nfs

  1. # 安装 nfs
  2. apt-get install nfs-common nfs-kernel-server -y
  3. #yum install nfs-utils -y
  4. # 创建共享目录
  5. mkdir -p /data/nfs
  6. cd /data/nfs
  7. mkdir rw
  8. mkdir ro
  9. # 设置共享目录 export
  10. vim /etc/exports
  11. /data/nfs/rw 192.168.122.0/24(insecure,rw,sync,no_subtree_check,no_root_squash)
  12. /data/nfs/ro 192.168.122.0/24(insecure,ro,sync,no_subtree_check,no_root_squash)
  13. # 启动 nfs
  14. systemctl start nfs-kernel-server.service
  15. #systemctl start nfs-server
  16. # 查看 nfs 版本
  17. cat /proc/fs/nfsd/versions
  18. # 到其他测试节点安装 nfs-utils 并加载测试
  19. mkdir -p /mnt/nfs/rw
  20. mount -t nfs 192.168.122.120:/data/nfs/rw /mnt/nfs/rw
复制代码
设置文件

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4.   name: nfs-test-pod
  5. spec:
  6.   containers:
  7.   - image: nginx
  8.     name: nfs-test-container
  9.     volumeMounts:
  10.     - mountPath: /data
  11.       name: test-volume
  12.   volumes:
  13.   - name: test-volume
  14.     nfs:
  15.       server: 192.168.122.120 # 网络存储服务地址
  16.       path: /data/nfs/rw # 网络存储路径
  17.       readOnly: false # 是否只读
复制代码
  1. 测试在其他node节点创建文件并在pod中查看
复制代码
5.2.3 PV与PVC

持久卷(PersistentVolume,PV) 是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 照旧特定于云平台的存储体系。
持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的哀求。概念上与 Pod 雷同。 Pod 会耗用节点资源,而 PVC 申了解耗用 PV 资源。Pod 可以哀求特定命量的资源(CPU 和内存);同样 PVC 申领也可以哀求特定的大小和访问模式 (比方,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载,参见访问模式)。
5.2.3.1 生命周期

构建

静态构建

集群管理员创建若干 PV 卷。这些卷对象带有真实存储的细节信息, 而且对集群用户可用(可见)。PV 卷对象存在于 Kubernetes API 中,可供用户消费(使用)。
动态构建

如果集群中已经有的 PV 无法满足 PVC 的需求,那么集群会根据 PVC 主动构建一个 PV,该操作是通过 StorageClass 实现的。
想要实现这个操作,条件是 PVC 必须设置 StorageClass,否则会无法动态构建该 PV,可以通过启用 DefaultStorageClass 来实现 PV 的构建。
绑定

当用户创建一个 PVC 对象后,主节点会监测新的 PVC 对象,而且探求与之匹配的 PV 卷,找到 PV 卷后将二者绑定在一起。
如果找不到对应的 PV,则需要看 PVC 是否设置 StorageClass 来决定是否动态创建 PV,若没有设置,PVC 就会同等处于未绑定状态,直到有与之匹配的 PV 后才会申领绑定关系。
使用

Pod 将 PVC 当作存储卷来使用,集群会通过 PVC 找到绑定的 PV,并为 Pod 挂载该卷。
Pod 一旦使用 PVC 绑定 PV 后,为了保护数据,避免数据丢失问题,PV 对象会受到保护,在体系中无法被删除。
回收计谋

当用户不再使用其存储卷时,他们可以从 API 中将 PVC 对象删除, 从而允许该资源被回收再使用。PersistentVolume 对象的回收计谋告诉集群, 当其被从申领中开释时怎样处理惩罚该数据卷。 现在,数据卷可以被 Retained(保留)、Recycled(回收)或 Deleted(删除)。
保留(Retain)

回收计谋 Retain 使得用户可以手动回收资源。当 PersistentVolumeClaim 对象被删除时,PersistentVolume 卷仍旧存在,对应的数据卷被视为"已开释(released)"。 由于卷上仍旧存在这前一申领人的数据,该卷还不能用于其他申领。 管理员可以通过下面的步骤来手动回收该卷:

  • 删除 PersistentVolume 对象。与之相关的、位于外部底子办法中的存储资产 (比方 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)在 PV 删除之后仍旧存在。
  • 根据环境,手动清除所关联的存储资产上的数据。
  • 手动删除所关联的存储资产。
如果你希望重用该存储资产,可以基于存储资产的定义创建新的 PersistentVolume 卷对象。
删除(Delete)

对于支持 Delete 回收计谋的卷插件,删除动作会将 PersistentVolume 对象从 Kubernetes 中移除,同时也会从外部底子办法(如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)中移除所关联的存储资产。 动态制备的卷会继续其 StorageClass 中设置的回收计谋, 该计谋默认为 Delete。管理员需要根据用户的盼望来设置 StorageClass; 否则 PV 卷被创建之后必须要被编辑或者修补。
回收(Recycle)

警告: 回收计谋 Recycle 已被废弃。取而代之的发起方案是使用动态制备。
如果下层的卷插件支持,回收计谋 Recycle 会在卷上执行一些基本的擦除 (rm -rf /thevolume/*)操作,之后允许该卷用于新的 PVC 申领。
5.2.3.2 PV

状态

Available: 空闲,未被绑定
Bound: 已经被PVC绑定
Released: PVC被删除,资源已回收,但是PV未被重新使用
Failed: 主动回收失败
设置文件

  1. apiVersion: v1
  2. kind: PersistentVolume
  3. metadata:
  4.   name: pv0001
  5. spec:
  6.   capacity:
  7.     storage: 5Gi # pv 的容量
  8.   volumeMode: Filesystem # 存储类型为文件系统
  9.   accessModes: # 访问模式:ReadWriteOnce、ReadWriteMany、ReadOnlyMany
  10.     - ReadWriteOnce # 可被单节点独写
  11.   persistentVolumeReclaimPolicy: Recycle # 回收策略
  12.   storageClassName: slow # 创建 PV 的存储类名,需要与 pvc 的相同
  13.   mountOptions: # 加载配置
  14.     - hard
  15.     - nfsvers=4.1
  16.   nfs: # 连接到 nfs
  17.     path: /data/nfs/rw/test-pv # 存储路径
  18.     server: 192.168.113.121 # nfs 服务地址
复制代码
5.2.3.3 PVC

Pod绑定PVC

  1. 在 pod 的挂载容器配置中,增加 pvc 挂载
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5.   name: test-pvc-pod
  6. spec:
  7.   containers:
  8.   - image: nginx
  9.     name: nginx-volume
  10.     volumeMounts:
  11.     - mountPath: /test-pod
  12.       name: test-volume
  13.   volumes:
  14.   - name: test-volume
  15.     persistentVolumeClaim:
  16.       claimName: nfs-pvc # pvc 的名称
复制代码
设置文件

  1. apiVersion: v1
  2. kind: PersistentVolumeClaim
  3. metadata:
  4.   name: nfs-pvc
  5. spec:
  6.   accessModes:
  7.     - ReadWriteOnce # 权限需要与对应的 pv 相同
  8.   volumeMode: Filesystem
  9.   resources:
  10.     requests:
  11.       storage: 5Gi # 资源可以小于 pv 的,但是不能大于,如果大于就会匹配不到 pv
  12.   storageClassName: slow # 名字需要与对应的 pv 相同
  13. #  selector: # 使用选择器选择对应的 pv
  14. #    matchLabels:
  15. #      release: "stable"
  16. #    matchExpressions:
  17. #      - {key: environment, operator: In, values: [dev]}
复制代码
5.2.3.4 StorageClass

制备器(Provisioner)

每个 StorageClass 都有一个制备器(Provisioner),用来决定使用哪个卷插件制备 PV。
NFS动态制存案例

参考文档1:https://kubernetes.io/docs/concepts/storage/storage-classes/
参考文档2:https://github.com/kubernetes-csi/csi-driver-nfs#readme
使用helm安装特定版本csi-driver-nfs
  1. helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts
  2. helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs --namespace kube-system --version v4.7.0
复制代码
创建storage class
  1. apiVersion: storage.k8s.io/v1
  2. kind: StorageClass
  3. metadata:
  4.   name: nfs-csi
  5. provisioner: nfs.csi.k8s.io
  6. parameters:
  7.   server: 192.168.122.120    # 改为自己的 nfs server
  8.   share: /data/nfs/rw    # 改为自己的nfs 共享路径
  9.   # csi.storage.k8s.io/provisioner-secret is only needed for providing mountOptions in DeleteVolume
  10.   # csi.storage.k8s.io/provisioner-secret-name: "mount-options"
  11.   # csi.storage.k8s.io/provisioner-secret-namespace: "default"
  12. reclaimPolicy: Delete
  13. volumeBindingMode: Immediate
  14. mountOptions:
  15.   - nfsvers=4.1
复制代码
创建PVC
  1. kubectl create -f https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/deploy/example/pvc-nfs-csi-dynamic.yaml
  2. # pvc-nfs-csi-dynamic.yaml文件内容:
  3. ---
  4. apiVersion: v1
  5. kind: PersistentVolumeClaim
  6. metadata:
  7.   name: pvc-nfs-dynamic
  8. spec:
  9.   accessModes:
  10.     - ReadWriteMany
  11.   resources:
  12.     requests:
  13.       storage: 10Gi
  14.   storageClassName: nfs-csi
复制代码
动态PVC测试
  1. apiVersion: v1
  2. kind: PersistentVolumeClaim
  3. metadata:
  4.   name: auto-pv-test-pvc
  5. spec:
  6.   accessModes:
  7.   - ReadWriteOnce
  8.   resources:
  9.     requests:
  10.       storage: 300Mi
  11.   storageClassName: nfs-csi
复制代码
检察结果
  1. kubectl get pvc
  2. kubectl get pv
  3. ls /data/nfs/rw
复制代码
注:以下部分由于quay.io/external_storage/nfs-client-provisioner:latest镜像截至2024/5/8已有6年未更新,新版docker已不支持该版镜像;其他镜像源经过测试也无法使用故删除
NFS动态制存案例

nfs-provisioner

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4.   name: nfs-client-provisioner
  5.   namespace: kube-system
  6.   labels:
  7.     app: nfs-client-provisioner
  8. spec:
  9.   replicas: 1
  10.   strategy:
  11.     type: Recreate
  12.   selector:
  13.     matchLabels:
  14.       app: nfs-client-provisioner
  15.   template:
  16.     metadata:
  17.       labels:
  18.         app: nfs-client-provisioner
  19.     spec:
  20.       serviceAccountName: nfs-client-provisioner
  21.       containers:
  22.         - name: nfs-client-provisioner
  23.           #image: quay.io/external_storage/nfs-client-provisioner:latest # 原镜像,被墙,无法直接访问
  24.           image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner:latest
  25.           volumeMounts:
  26.             - name: nfs-client-root
  27.               mountPath: /persistentvolumes
  28.           env:
  29.             - name: PROVISIONER_NAME
  30.               value: fuseim.pri/ifs
  31.             - name: NFS_SERVER
  32.               value: 192.168.122.120
  33.             - name: NFS_PATH
  34.               value: /data/nfs/rw
  35.       volumes:
  36.         - name: nfs-client-root
  37.           nfs:
  38.             server: 192.168.122.120
  39.             path: /data/nfs/rw
复制代码
StorageClass设置

  1. apiVersion: storage.k8s.io/v1
  2. kind: StorageClass
  3. metadata:
  4.   name: managed-nfs-storage
  5.   namespace: kube-system
  6. provisioner: fuseim.pri/ifs # 外部制备器提供者,编写为提供者的名称
  7. parameters:
  8.   archiveOnDelete: "false" # 是否存档,false 表示不存档,会删除 oldPath 下面的数据,true 表示存档,会重命名路径
  9. reclaimPolicy: Retain # 回收策略,默认为 Delete 可以配置为 Retain
  10. volumeBindingMode: Immediate # 默认为 Immediate,表示创建 PVC 立即进行绑定,只有 azuredisk 和 AWSelasticblockstore 支持其他值
复制代码
RBAC设置

  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4.   name: nfs-client-provisioner
  5.   namespace: kube-system
  6. ---
  7. kind: ClusterRole
  8. apiVersion: rbac.authorization.k8s.io/v1
  9. metadata:
  10.   name: nfs-client-provisioner-runner
  11.   namespace: kube-system
  12. rules:
  13.   - apiGroups: [""]
  14.     resources: ["persistentvolumes"]
  15.     verbs: ["get", "list", "watch", "create", "delete"]
  16.   - apiGroups: [""]
  17.     resources: ["persistentvolumeclaims"]
  18.     verbs: ["get", "list", "watch", "update"]
  19.   - apiGroups: ["storage.k8s.io"]
  20.     resources: ["storageclasses"]
  21.     verbs: ["get", "list", "watch"]
  22.   - apiGroups: [""]
  23.     resources: ["events"]
  24.     verbs: ["create", "update", "patch"]
  25. ---
  26. kind: ClusterRoleBinding
  27. apiVersion: rbac.authorization.k8s.io/v1
  28. metadata:
  29.   name: run-nfs-client-provisioner
  30.   namespace: kube-system
  31. subjects:
  32.   - kind: ServiceAccount
  33.     name: nfs-client-provisioner
  34.     namespace: default
  35. roleRef:
  36.   kind: ClusterRole
  37.   name: nfs-client-provisioner-runner
  38.   apiGroup: rbac.authorization.k8s.io
  39. ---
  40. kind: Role
  41. apiVersion: rbac.authorization.k8s.io/v1
  42. metadata:
  43.   name: leader-locking-nfs-client-provisioner
  44.   namespace: kube-system
  45. rules:
  46.   - apiGroups: [""]
  47.     resources: ["endpoints"]
  48.     verbs: ["get", "list", "watch", "create", "update", "patch"]
  49. ---
  50. kind: RoleBinding
  51. apiVersion: rbac.authorization.k8s.io/v1
  52. metadata:
  53.   name: leader-locking-nfs-client-provisioner
  54.   namespace: kube-system
  55. subjects:
  56.   - kind: ServiceAccount
  57.     name: nfs-client-provisioner
  58. roleRef:
  59.   kind: Role
  60.   name: leader-locking-nfs-client-provisioner
  61.   apiGroup: rbac.authorization.k8s.io
复制代码
  1. 创建rbac
  2. kubectl apply -f rbac.yaml
  3. 创建deployment
  4. kubectl apply -f deployment.yaml
  5. 创建storage class
  6. kubectl apply -f storageclass.yaml
复制代码
PVC处于Pending状态

在 k8s 1.20 之后,出于对性能和同一 apiserver 调用方式的初衷,移除了对 SelfLink 的支持,而默认上面指定的 provisioner 版本需要 SelfLink 功能,因此 PVC 无法进行主动制备。


  • 设置SelfLink
    1. 修改 apiserver 配置文件
    2. vim /etc/kubernetes/manifests/kube-apiserver.yaml
    3. spec:
    4.   containers:
    5.   - command:
    6.     - kube-apiserver
    7.     - --feature-gates=RemoveSelfLink=false # 新增该行
    8.     ......
    9. 修改后重新应用该配置
    10. kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
    复制代码
  • 不需要SelfLink的provisioner
    将 provisioner 修改为如下镜像之一即可
    gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0
    registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0
PVC测试设置

  1. apiVersion: v1
  2. kind: PersistentVolumeClaim
  3. metadata:
  4.   name: auto-pv-test-pvc
  5. spec:
  6.   accessModes:
  7.   - ReadWriteOnce
  8.   resources:
  9.     requests:
  10.       storage: 300Mi
  11.   storageClassName: managed-nfs-storage
复制代码
六、高级调理

6.1 CronJob计划任务

cron表达式

  1. # ┌───────────── 分钟 (0 - 59)
  2. # │ ┌───────────── 小时 (0 - 23)
  3. # │ │ ┌───────────── 月的某天 (1 - 31)
  4. # │ │ │ ┌───────────── 月份 (1 - 12)
  5. # │ │ │ │ ┌───────────── 周的某天 (0 - 6)(周日到周一;在某些系统上,7 也是星期日)
  6. # │ │ │ │ │                          或者是 sun,mon,tue,web,thu,fri,sat
  7. # │ │ │ │ │
  8. # │ │ │ │ │
  9. # * * * * *
复制代码
设置文件

  1. apiVersion: batch/v1
  2. kind: CronJob
  3. metadata:
  4.   name: hello
  5. spec:
  6.   concurrencyPolicy: Allow # 并发调度策略:Allow 允许并发调度,Forbid:不允许并发执行,Replace:如果之前的任务还没执行完,就直接执行新的,放弃上一个任务
  7.   failedJobsHistoryLimit: 1 # 保留多少个失败的任务
  8.   successfulJobsHistoryLimit: 3 # 保留多少个成功的任务
  9.   suspend: false # 是否挂起任务,若为 true 则该任务不会执行
  10. #  startingDeadlineSeconds: 30 # 间隔多长时间检测失败的任务并重新执行,时间不能小于 10
  11.   schedule: "* * * * *" # 调度策略
  12.   jobTemplate:
  13.     spec:
  14.       template:
  15.         spec:
  16.           containers:
  17.           - name: hello
  18.             image: busybox:1.28
  19.             imagePullPolicy: IfNotPresent
  20.             command:
  21.             - /bin/sh
  22.             - -c
  23.             - date; echo Hello from the Kubernetes cluster
  24.           restartPolicy: OnFailure
复制代码
6.2 初始化容器InitContainer

在真正的容器启动之前,先启动 InitContainer,在初始化容器中完成真实容器所需的初始化操作,完成后再启动真实的容器。
相对于 postStart 来说,起首 InitController 能够包管一定在 EntryPoint 之前执行,而 postStart 不能,其次 postStart 更适合去执行一些下令操作,而 InitController 现实就是一个容器,可以在其他底子容器环境下执行更复杂的初始化功能。
  1. 在 pod 创建的模板中配置 initContainers 参数:
  2. spec:
  3.   initContainers:
  4.   - image: nginx
  5.     imagePullPolicy: IfNotPresent
  6.     command: ["sh", "-c", "echo 'inited;' >> ~/.init"]
  7.     name: init-test
复制代码
6.3 污点与容忍

k8s 集群中可能管理着非常巨大的服务器,这些服务器可能是各种各样不同类型的,比如机房、地理位置、设置等,有些是计算型节点,有些是存储型节点,此时我们希望能更好的将 pod 调理到与之需求更匹配的节点上。
此时就需要用到污点(Taint)和容忍(Toleration),这些设置都是 key: value 类型的。
6.3.1 污点(Taint)

污点:是标注在节点上的,当我们在一个节点上打上污点以后,k8s 会认为尽量不要将 pod 调理到该节点上,除非该 pod 上面表现可以容忍该污点,且一个节点可以打多个污点,此时则需要 pod 容忍全部污点才会被调理该节点。
  1. # 为节点打上污点
  2. kubectl taint node k8s-master key=value:NoSchedule
  3. # 移除污点
  4. kubectl taint node k8s-master key=value:NoSchedule-
  5. # 查看污点
  6. kubectl describe no k8s-master
复制代码
污点的影响:
NoSchedule:不能容忍的 pod 不能被调理到该节点,但是已经存在的节点不会被驱逐
NoExecute:不能容忍的节点会被立即清除,能容忍且没有设置 tolerationSeconds 属性,则可以一直运行,设置了 tolerationSeconds: 3600 属性,则该 pod 还能继续在该节点运行 3600 秒
NoSchedule

如果不能容忍该污点,那么 Pod 就无法调理到该节点上
NoExecute



  • 如果 Pod 不能忍受这类污点,Pod 会立刻被驱逐。
  • 如果 Pod 能够忍受这类污点,但是在容忍度定义中没有指定 tolerationSeconds, 则 Pod 还会一直在这个节点上运行。
  • 如果 Pod 能够忍受这类污点,而且指定了 tolerationSeconds, 则 Pod 还能在这个节点上继续运行这个指定的时间长度。
6.3.2 容忍(Toleration)

容忍:是标注在 pod 上的,当 pod 被调理时,如果没有设置容忍,则该 pod 不会被调理到有污点的节点上,只有该 pod 上标注了满足某个节点的全部污点,则会被调理到这些节点
  1. # pod 的 spec 下面配置容忍
  2. tolerations:
  3. - key: "污点的 key"
  4.   value: "污点的 value"
  5.   offect: "NoSchedule" # 污点产生的影响
  6.   operator: "Equal" # 表是 value 与污点的 value 要相等,也可以设置为 Exists 表示存在 key 即可,此时可以不用配置 value
复制代码
Equal

比较操作类型为 Equal,则意味着必须与污点值做匹配,key/value都必须相同,才表现能够容忍该污点
Exists

容忍与污点的比较只比较 key,不比较 value,不关心 value 是什么东西,只要 key 存在,就表现可以容忍。
6.4 亲和力

6.4.1 NodeAffinity

节点亲和力:进行 pod 调理时,优先调理到符合条件的亲和力节点上
RequiredDuringSchedulingIgnoredDuringExecution

硬亲和力,即支持必须部署在指定的节点上,也支持必须不部署在指定的节点上
PreferredDuringSchedulingIgnoredDuringExecution

软亲和力:尽量部署在满足条件的节点上,或尽量不要部署在被匹配的节点上
应用

匹配类型



  • In:部署在满足条件的节点上
  • Noth:匹配不在条件中的节点,实现节点反亲和性
  • Exists:只要存在 key 名字就可以,不关心值是什么
  • DoesNotExist:匹配指定 key 名不存在的节点,实现节点反亲和性
  • Gt:value 为数值,且节点上的值小于指定的条件
  • Lt:value 为数值,且节点上的值大于指定条件
设置模板

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4.   name: with-node-affinity
  5. spec:
  6.   affinity: # 亲和力配置
  7.     nodeAffinity: # 节点亲和力
  8.       requiredDuringSchedulingIgnoredDuringExecution: # 节点必须匹配下方配置
  9.         nodeSelectorTerms: # 选择器
  10.         - matchExpressions: # 匹配表达式
  11.           - key: topology.kubernetes.io/zone # 匹配 label 的 key
  12.             operator: In # 匹配方式,只要匹配成功下方的一个 value 即可
  13.             values:
  14.             - antarctica-east1 # 匹配的 value
  15.             - antarctica-west1 # 匹配的 value
  16.       preferredDuringSchedulingIgnoredDuringExecution: # 节点尽量匹配下方配置
  17.       - weight: 1 # 权重[1,100],按照匹配规则对所有节点累加权重,最终之和会加入优先级评分,优先级越高被调度的可能性越高
  18.         preference:
  19.           matchExpressions: # 匹配表达式
  20.           - key: another-node-label-key # label 的 key
  21.             operator: In # 匹配方式,满足一个即可
  22.             values:
  23.             - another-node-label-value # 匹配的 value
  24. #      - weight: 20
  25.         ......
  26.   containers:
  27.   - name: with-node-affinity
  28.     image: pause:2.0
复制代码
  1. 为node打标签
  2. kubectl label nodes k8s-node1 security=S1
复制代码
6.4.2 PodAffinity

Pod 亲和力:将与指定 pod 亲和力相匹配的 pod 部署在同一节点。
RequiredDuringSchedulingIgnoredDuringExecution

必须将应用部署在一块
PreferredDuringSchedulingIgnoredDuringExecution

尽量将应用部署在一块
设置模板

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4.   name: with-pod-affinity
  5. spec:
  6.   affinity: # 亲和力配置
  7.     podAffinity: # pod 亲和力配置
  8.       requiredDuringSchedulingIgnoredDuringExecution: # 当前 pod 必须匹配到对应条件 pod 所在的 node 上
  9.       - labelSelector: # 标签选择器
  10.           matchExpressions: # 匹配表达式
  11.           - key: security # 匹配的 key
  12.             operator: In # 匹配方式
  13.             values: # 匹配其中的一个 value
  14.             - S1
  15.         topologyKey: topology.kubernetes.io/zone
  16.     podAntiAffinity: # pod 反亲和力配置
  17.       preferredDuringSchedulingIgnoredDuringExecution: # 尽量不要将当前节点部署到匹配下列参数的 pod 所在的 node 上
  18.       - weight: 100 # 权重
  19.         podAffinityTerm: # pod 亲和力配置条件
  20.           labelSelector: # 标签选择器
  21.             matchExpressions: # 匹配表达式
  22.             - key: security # 匹配的 key
  23.               operator: In # 匹配的方式
  24.               values:
  25.               - S2 # 匹配的 value
  26.           topologyKey: topology.kubernetes.io/zone
  27.   containers:
  28.   - name: with-pod-affinity
  29.     image: pause:2.0
复制代码
6.4.3 PodAntiAffinity

Pod 反亲和力:根据计谋尽量部署或不部署到一块
RequiredDuringSchedulingIgnoredDuringExecution

不要将应用与之匹配的部署到一块
  1.         podAffinity:
  2.           requiredDuringSchedulingIgnoredDuringExecution:
  3.           - labelSelector:
  4.               matchExpressions:
  5.               - key: security
  6.                 operator: In
  7.                 values:
  8.                 - S1
  9.             topologyKey: topology.kubernetes.io/zone
复制代码
PreferredDuringSchedulingIgnoredDuringExecution

尽量不要将应用部署到一块
七、身份认证与权限

Kubernetes 中提供了精良的多租户认证管理机制,如 RBAC、ServiceAccount 另有各种计谋等。
通过该文件可以看到已经设置了 RBAC 访问控制
/usr/lib/systemd/system/kube-apiserver.service
7.1 认证

全部 Kubernetes 集群有两类用户:由 Kubernetes 管理的Service Accounts (服务账户)和(Users Accounts) 普通账户。
普通账户是假定被外部或独立服务管理的,由管理员分配 keys,用户像使用 Keystone 或 google 账号一样,被存储在包罗 usernames 和 passwords 的 list 的文件里。
需要注意:在 Kubernetes 中不能通过 API 调用将普通用户添加到集群中


  • 普通帐户是针对(人)用户的,服务账户针对 Pod 进程。
  • 普通帐户是全局性。在集群全部namespaces中,名称具有惟一性。
  • 通常,聚集的普通帐户可以与企业数据库同步,新的普通帐户创建需要特殊权限。服务账户创建目的是更轻量化,允许集群用户为特定任务创建服务账户。
  • 普通帐户和服务账户的审核注意事项不同。
  • 对于复杂体系的设置包,可以包罗对该体系的各种组件的服务账户的定义。
7.1.1 User Accounts

7.1.2 Service Accounts

Service Account 主动化

Service Account Admission Controller

通过 Admission Controller 插件来实现对 pod 修改,它是 apiserver 的一部分。创建或更新 pod 时会同步进行修改 pod。当插件处于激活状态(在大多数发行版中都默认环境)创建或修改 pod 时,会按以下操作执行:

  • 如果 pod 没有设置 ServiceAccount,则将 ServiceAccount 设置为 default。
  • 确保 pod 引用的 ServiceAccount 存在,否则将会拒绝哀求。
  • 如果 pod 不包罗任何 ImagePullSecrets,则将ServiceAccount 的 ImagePullSecrets 会添加到 pod 中。
  • 为包罗 API 访问的 Token 的 pod 添加了一个 volume。
  • 把 volumeSource 添加到安装在 pod 的每个容器中,挂载在 /var/run/secrets/kubernetes.io/serviceaccount。
Token Countroller

TokenController 作为 controller-manager 的一部分运行。异步行为:


  • 观察 serviceAccount 的创建,并创建一个相应的 Secret 来允许 API 访问。
  • 观察 serviceAccount 的删除,并删除全部相应的ServiceAccountToken Secret
  • 观察 secret 添加,并确保关联的 ServiceAccount 存在,并在需要时向 secret 中添加一个 Token。
  • 观察 secret 删除,并在需要时对应 ServiceAccount 的关联
Service Account Controller

Service Account Controller 在 namespaces 里管理ServiceAccount,并确保每个有用的 namespaces 中都存在一个名为 “default” 的 ServiceAccount。
7.2 授权(RBAC)

7.2.1 Role

代表一个脚色,会包罗一组权限,没有拒绝规则,只是附加允许。它是 Namespace 级别的资源,只能作用与 Namespace 之内。
  1. # 查看已有的角色信息
  2. kubectl get role -n ingress-nginx -oyaml
复制代码
设置文件

  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: Role
  3. metadata:
  4.   labels:
  5.     app.kubernetes.io/name: ingress-nginx
  6.     app.kubernetes.io/part-of: ingress-nginx
  7.   name: nginx-ingress
  8.   namespace: ingress-nginx
  9. roles:
  10. - apiGroups:
  11.   - ""
  12.   resources:
  13.   - configmaps
  14.   - pods
  15.   - secrets
  16.   - namespaces
  17.   verbs:
  18.   - get
  19. - apiGroups:
  20.   - ""
  21.   resourceNames:
  22.   - ingress-controller-label-nginx
  23.   resources:
  24.   - configmaps
  25.   verbs:
  26.   - get
  27.   - update
  28. - apiGroups:
  29.   - ""
  30.   resources:
  31.   - configmaps
  32.   verbs:
  33.   - create
复制代码
7.2.2 ClusterRole

功能与 Role 一样,区别是资源类型为集群类型,而 Role 只在 Namespace
  1. # 查看某个集群角色的信息
  2. kubectl get clusterrole view -oyaml
复制代码
7.2.3 RoleBinding

Role 或 ClusterRole 只是用于制定权限集合,详细作用与什么对象上,需要使用 RoleBinding 来进行绑定。
作用于 Namespace 内,可以将 Role 或 ClusterRole 绑定到 User、Group、Service Account 上。
  1. # 查看 rolebinding 信息
  2. kubectl get rolebinding --all-namespaces
  3. # 查看指定 rolebinding 的配置信息
  4. kubectl get rolebinding <role_binding_name> --all-namespaces -oyaml
复制代码
设置文件

  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: RoleBinding
  3. metadata:
  4.   ......
  5. roleRef:
  6.   apiGroup: rbac.authorization.k8s.io
  7.   kind: Role
  8.   name nginx-ingress-role
  9. subjects:
  10. - kind: ServiceAccount
  11.   name: nginx-ingress-serviceaccount
  12.   namespace: ingress-nginx
复制代码
7.2.4 ClusterRoleBinding

与 RoleBinding 相同,但是作用于集群之上,可以绑定到该集群下的恣意 User、Group 或 Service Account

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

悠扬随风

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表