今天内容

  1. kubernetes 部署

  2. Node and Cluster

  3. Namespace and Contexts

Kubernetes 安装

创建集群

下载镜像

在master节点初始化集群过程中,需要下载镜像,这里我们提前下载。

 [root@master30 ~]# kubeadm config images pull --kubernetes-version=v1.30.2
 [config/images] Pulled registry.k8s.io/kube-apiserver:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-controller-manager:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-scheduler:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-proxy:v1.30.2
 [config/images] Pulled registry.k8s.io/coredns/coredns:v1.11.1
 [config/images] Pulled registry.k8s.io/pause:3.9
 [config/images] Pulled registry.k8s.io/etcd:3.5.12-0

备选方案-使用阿里云仓库镜像:

 [root@master30 ~]# kubeadm config images pull --kubernetes-version=v1.30.2 --image-repository registry.aliyuncs.com/google_containers
 [config/images] Pulled registry.k8s.io/kube-apiserver:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-controller-manager:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-scheduler:v1.30.2
 [config/images] Pulled registry.k8s.io/kube-proxy:v1.30.2
 [config/images] Pulled registry.k8s.io/coredns/coredns:v1.11.1
 [config/images] Pulled registry.k8s.io/pause:3.9
 [config/images] Pulled registry.k8s.io/etcd:3.5.12-0

worker 节点需要kube-proxy和pause镜像:

 [root@worker31 ~]# nerdctl pull registry.k8s.io/kube-proxy:v1.30.2
 [root@worker31 ~]# nerdctl pull registry.k8s.io/pause:3.9
 ​
 [root@worker32 ~]# nerdctl pull registry.k8s.io/kube-proxy:v1.30.2
 [root@worker32 ~]# nerdctl pull registry.k8s.io/pause:3.9

初始化集群

 #这条命令是搭建 K8s 集群的第一步:在当前 master30 机器上,创建整套集群控制平面(Master 主控节点)
 #自动部署 apiserver、etcd、调度器、控制器管理器 四大核心组件,同时生成:1.集群根 CA 证书、管理员凭证(就是你之前一直在用的 /root/.kube/config 文件来源)  2.工作节点加入集群的 kubeadm join 加入指令  3.Pod 网络通信网段定义
 [root@master30 ~]# kubeadm init --kubernetes-version=v1.30.2 --pod-network-cidr=10.224.0.0/16 

备选方案-使用阿里云仓库镜像初始化集群:

 [root@master30 ~]# kubeadm init --kubernetes-version=v1.30.2 --pod-network-cidr=10.224.0.0/16  --image-repository registry.aliyuncs.com/google_containers (使用阿里云仓库初始化集群需要多加参数)

初始化过程如下:

 [init] Using Kubernetes version: v1.30.2
 [preflight] Running pre-flight checks
 [preflight] Pulling images required for setting up a Kubernetes cluster
 [preflight] This might take a minute or two, depending on the speed of your internet connection
 [preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
 [certs] Using certificateDir folder "/etc/kubernetes/pki"
 [certs] Generating "ca" certificate and key
 [certs] Generating "apiserver" certificate and key
 [certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master30.laoma.cloud] and IPs [10.96.0.1 10.1.8.30]
 [certs] Generating "apiserver-kubelet-client" certificate and key
 [certs] Generating "front-proxy-ca" certificate and key
 [certs] Generating "front-proxy-client" certificate and key
 [certs] Generating "etcd/ca" certificate and key
 [certs] Generating "etcd/server" certificate and key
 [certs] etcd/server serving cert is signed for DNS names [localhost master30.laoma.cloud] and IPs [10.1.8.30 127.0.0.1 ::1]
 [certs] Generating "etcd/peer" certificate and key
 [certs] etcd/peer serving cert is signed for DNS names [localhost master30.laoma.cloud] and IPs [10.1.8.30 127.0.0.1 ::1]
 [certs] Generating "etcd/healthcheck-client" certificate and key
 [certs] Generating "apiserver-etcd-client" certificate and key
 [certs] Generating "sa" key and public key
 [kubeconfig] Using kubeconfig folder "/etc/kubernetes"
 [kubeconfig] Writing "admin.conf" kubeconfig file
 [kubeconfig] Writing "super-admin.conf" kubeconfig file
 [kubeconfig] Writing "kubelet.conf" kubeconfig file
 [kubeconfig] Writing "controller-manager.conf" kubeconfig file
 [kubeconfig] Writing "scheduler.conf" kubeconfig file
 [etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
 [control-plane] Using manifest folder "/etc/kubernetes/manifests"
 [control-plane] Creating static Pod manifest for "kube-apiserver"
 [control-plane] Creating static Pod manifest for "kube-controller-manager"
 [control-plane] Creating static Pod manifest for "kube-scheduler"
 [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
 [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
 [kubelet-start] Starting the kubelet
 [wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests"
 [kubelet-check] Waiting for a healthy kubelet. This can take up to 4m0s
 [kubelet-check] The kubelet is healthy after 502.398615ms
 [api-check] Waiting for a healthy API server. This can take up to 4m0s
 [api-check] The API server is healthy after 7.50265248s
 [upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
 [kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
 [upload-certs] Skipping phase. Please see --upload-certs
 [mark-control-plane] Marking the node master30.laoma.cloud as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
 [mark-control-plane] Marking the node master30.laoma.cloud as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
 [bootstrap-token] Using token: ybenal.6mszwb1nf8nck72g
 [bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
 [bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
 [bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
 [bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
 [bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
 [bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
 [kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
 [addons] Applied essential addon: CoreDNS
 [addons] Applied essential addon: kube-proxy
 ​
 Your Kubernetes control-plane has initialized successfully!
 ​
 To start using your cluster, you need to run the following as a regular user:
 ​
   mkdir -p $HOME/.kube
   sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
   sudo chown $(id -u):$(id -g) $HOME/.kube/config
 ​
 Alternatively, if you are the root user, you can run:
 ​
   export KUBECONFIG=/etc/kubernetes/admin.conf
 ​
 You should now deploy a pod network to the cluster.
 Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
   https://kubernetes.io/docs/concepts/cluster-administration/addons/
 ​
 Then you can join any number of worker nodes by running the following on each as root:
 ​
 kubeadm join 10.1.8.30:6443 --token mi0yt8.1tzza4q64dr8y3pc \
     --discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd

选项说明:

--image-repository registry.aliyuncs.com/google_containers,指定镜像下载位置

--kubernetes-version=v1.30.2,指定版本

--pod-network-cidr=10.224.0.0/16,指定Pod网络的范围。 Kubernetes支持多种网络 方案, 而且不同网络方案对--pod-network-cidr有自己的要求。

--apiserver-advertise-address指明用哪个interface与Cluster的其他节点通信。 如果master有多个interface, 建议明确指定, 如果不指定, kubeadm会自动选择有默认网关的interface。

初始化过程说明:

  1. kubeadm执行初始化前的检查。

  2. 下载组件的镜像。 这一步可能会花一些时间, 主要取决于网络质量。

  3. 生成token和证书。

  4. 生成KubeConfig文件, kubelet需要用这个文件与master通信。

  5. 安装master组件。

  6. 安装附加组件kube-proxy和CoreDNS。

  7. Kubernetes master初始化成功。

  8. 提示如何配置kubectl。

  9. 提示如何安装Pod网络。

  10. 提示如何注册其他节点到Cluster。

配置集群

配置凭据

  1. kubectl默认使用~/.kube/config文件中凭据信息管理kubernetes。

 #$HOME:当前用户家目录,root 用户等价 /root
 #作用:创建 kubectl 默认存放凭证的隐藏目录 .kube
 [root@master30 ~ 09:49:09]# mkdir -p $HOME/.kube
 ​
 ​
 #/etc/kubernetes/admin.conf:kubeadm 初始化集群后自动生成的管理员完整凭证文件(集群 master 自带)
 #$HOME/.kube/config:复制到 kubectl 默认读取位置
 #效果:直接执行 kubectl 无需额外指定凭证,即可操作集群()
 [root@master30 ~ 09:50:10]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  1. 如果环境变量KUBECONFIG存在,则优先使用境变量KUBECONFIG设置的值。

 [root@master30 ~ 09:45:37]# mv .kube/config  .
 [root@master30 ~ 09:50:10]# ls
 calico.yaml  config  kubeadm.yaml  kubectx-master  kubectx.zip  ns-zy.yaml
 ​
 #KUBECONFIG:kubectl 专属环境变量,优先级高于默认~/.kube/config
 #赋值 /root/config:告诉 kubectl 去这个路径读取凭证
 [root@master30 ~ 09:55:42]# export KUBECONFIG=/root/config
 ​
 #NotReady:节点未就绪,通常是CNI 网络插件未部署,部署网络组件后状态变为 Ready
 [root@master30 ~ 09:58:11]# kubectl get nodes
 NAME                 STATUS     ROLES                  AGE    VERSION
 master30..cloud   NotReady   control-plane,master   5m2s   v1.28.2
 ​
 # 等网络配置完成后,STATUS状态由NotReady变更为Ready
  1. 还可以通过选项--kubeconfig=''明确指定凭据文件位置。

 [root@master30 ~ 09:58:17]# kubectl  get nodes  --kubeconfig  /root/config 
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   12h   v1.30.2
 worker31.zy.cloud   Ready    <none>          12h   v1.30.2
 worker32.zy.cloud   Ready    <none>          12h   v1.30.2
 ​
 #kubernetes对凭据文件名没有要求。
 #比如把config重命名为kube.conf
 [root@master30 ~ 10:00:40]# mv config  kube.conf  
 [root@master30 ~ 10:01:57]# kubectl  get  nodes --kubeconfig  /root/kube.conf 
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   12h   v1.30.2
 worker31.zy.cloud   Ready    <none>          12h   v1.30.2
 worker32.zy.cloud   Ready    <none>          12h   v1.30.2
 ​
  1. 恢复使用默认位置~/.kube/config

 [root@master30 ~ 10:02:03]# unset  KUBECONFIG
 [root@master30 ~ 10:02:44]# mv kube.conf    .kube/config
 ​

凭证文件优先级总结(从高到低) 1.--kubeconfig 命令行显式指定文件 2.环境变量 KUBECONFIG 指定路径 3.默认路径 ~/.kube/config

 # 配置普通用户 kubectl 访问权限置凭据:意思是把集群管理员的身份证书复制到当前用户专属目录,并修改权限,让当前用户拥有集群管理员权限,无需 sudo 即可操作集群。
 [root@master30 ~ 21:03:24]# mkdir  -p $HOME/.kube
 [root@master30 ~ 21:05:41]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 [root@master30 ~ 21:06:07]# sudo chown  $(id -u):$(id -g) $HOME/.kube/config 
 ​
 ​
 /etc/kubernetes/admin.conf:集群最高管理员证书,只有 root 可读;
 复制到当前用户家目录 .kube/config,普通用户不用 sudo 就能执行 kubectl;
 chown 修改文件归属为当前登录用户,否则会权限不足。
 ​
 ​
 #一、为什么要 配置普通用户 kubectl 访问权限置凭据
 kubectl 是操作 K8s 集群的命令工具,它访问集群 kube-apiserver 需要身份证书,证明你是管理员。
 集群初始化后,管理员证书文件放在这里:
 /etc/kubernetes/admin.conf
 这是集群最高权限凭证,只有 root 用户能读取。
 下面三条命令,就是把这份管理员证书复制到普通用户目录,让你不用 sudo 就能直接敲 kubectl:
 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 sudo chown $(id -u):$(id -g) $HOME/.kube/config
 生成的文件:~/.kube/config,行业内统称 kubeconfig 管理员凭证文件。
 ​
 #二、为什么必须配置
 1. 不配置的后果
 直接执行 kubectl get nodes 会报错:
 要么提示找不到 .kube/config;
 要么权限不足,必须加 sudo kubectl get nodes。
 每次操作都加 sudo 很麻烦,而且脚本、自动化工具不方便使用。
 2. 文件权限限制
 /etc/kubernetes/admin.conf 归属 root,普通用户读取不了,直接用会鉴权失败。
 把它复制到自己家目录,再修改文件属主为当前登录用户,普通用户就能正常读取证书。
 3. 作用原理
 kubectl 默认会自动读取 ~/.kube/config,里面包含:
 apiserver 集群地址
 CA 根证书
 管理员客户端证书、私钥
 每次执行 kubectl 命令,都会带着这份证书去和 apiserver 做 TLS 加密身份校验,集群识别你是管理员,才允许增删改查所有资源。
 4. 一句话总结含义
 把集群管理员的身份证书复制到当前用户专属目录,并修改权限,让当前用户拥有集群管理员权限,无需 sudo 即可操作集群。
 #比如我做实验验证:
 [root@master30 ~ 21:19:47]# cd .kube/
 [root@master30 .kube 21:19:59]# ls
 cache  config
 [root@master30 .kube 21:19:59]# cd
 #把.kube/config移走到当前目录下
 [root@master30 ~ 21:20:10]# mv  .kube/config   .
 [root@master30 ~ 21:20:25]# ls
 calico.yaml  config  kubeadm.yaml
 #验证kubectl命令是否可以使用,发现不行
 [root@master30 ~ 21:20:26]# kubectl  get  nodes
 E0705 21:20:36.901546  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.901874  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.907567  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.907748  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.909579  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 The connection to the server localhost:8080 was refused - did you specify the right host or port?
 [root@master30 ~ 21:20:36]# kubectl  get  pods
 E0705 21:20:43.463915  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.464846  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.466617  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.466831  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.468341  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 The connection to the server localhost:8080 was refused - did you specify the right host or port?
 #把config文件再移回到.kube/config
 [root@master30 ~ 21:20:43]# mv config  .kube/
 #发现kubectl命令可以执行
 [root@master30 ~ 21:20:55]# kubectl  get  pods
 No resources found in default namespace.
 [root@master30 ~ 21:20:59]# kubectl  get  nodes
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   17m   v1.30.2
 worker31.zy.cloud   Ready    <none>          11m   v1.30.2
 worker32.zy.cloud   Ready    <none>          10m   v1.30.2

部署网络

这里采用 calico 网络。

官方地址:http://projectcalico.org 或者 Project Calico | Tigera – Creator of Calico

产品文档:https://projectcalico.docs.tigera.io/about/about-calico

项目地址:GitHub - projectcalico/calico: Cloud native networking and network security · GitHub(提供镜像)

前置说明 K8s 集群初始化完成后缺少 CNI 网络插件,节点会一直NotReady,这里选用 Calico 作为 Pod 网络方案;流程分为:下载 Calico 清单→匹配集群 Pod 网段→预拉镜像→部署 Calico→worker 节点加入集群→全集群验证。

下载 calico 配置
 [root@master30 ~]# wget --no-check-certificate https://raw.githubusercontent.com/projectcalico/calico/v3.30.7/manifests/calico.yaml
 ​
 1.wget:文件下载工具
 2.--no-check-certificate:不校验 SSL 证书,国内服务器访问 github raw 常证书报错,加此参数跳过验证
 3.链接:官方提供的 Calico 完整资源清单,包含 DaemonSet、Deployment、ConfigMap、RBAC 等所有网络组件定义
 4.作用:本地得到calico.yaml,后续修改网段并部署到集群
修改 pod 网络
 # 查看集群 pod 网络范围
 [root@master30 ~ 21:18:52]# kubectl get cm -n kube-system kubeadm-config -o yaml|grep podSubnet
       podSubnet: 10.224.0.0/16
       
       
 #kubectl get cm:查询 ConfigMap 配置资源
 #-n kube-system:指定命名空间,kubeadm 初始化配置存于 kube-system
 #kubeadm-config:kubeadm 记录集群初始化参数的配置文件
 #-o yaml:以 yaml 格式完整输出配置内容
 #|grep podSubnet:管道过滤,只输出 Pod 网段配置行
 #输出podSubnet: 10.224.0.0/16:集群所有 Pod 分配的 IP 段,Calico 必须和这个网段保持一致,否则 Pod 网络不通
 ​
 # 更改 calico.yml,确保 CALICO_IPV4POOL_CIDR 与集群初始化的pod网络一致。
 [root@master30 ~ 22:11:52]# sed -i "s|# - name: CALICO_IPV4POOL_CIDR|- name: CALICO_IPV4POOL_CIDR|g" calico.yaml
 ​
 #sed -i:直接编辑文件,无需输出到控制台
 #s|匹配内容|替换内容|g:全局替换语法,用|分隔避免和 IP 斜杠冲突
 #匹配# - name: CALICO_IPV4POOL_CIDR:原文这一行是注释状态(带 #)
 #替换为- name: CALICO_IPV4POOL_CIDR:去掉注释,启用网段配置项
 ​
 [root@master30 ~ 23:8:52]# sed -i "s|#   value: \"192.*|  value: \"10.224.0.0/16\"|g" calico.yaml
 ​
 ​
 # value: "192.*":正则匹配原注释里默认 192 网段的配置
 #替换为value: "10.224.0.0/16":写入当前集群真实 Pod 网段,和 kubeadm 配置保持统一
 #两条命令合起来:开启 Calico IPv4 地址池并指定集群 Pod 网段
下载镜像
 [root@master30 ~ 21:19:06]# grep  image: calico.yaml 
           image: docker.io/calico/cni:v3.30.7
           image: docker.io/calico/node:v3.30.7
           image: docker.io/calico/kube-controllers:v3.30.7
 ​
 # 所有节点下载以上镜像
 [root@all-node ~]# nerdctl pull docker.io/calico/cni:v3.30.7
 [root@all-node ~]# nerdctl pull docker.io/calico/node:v3.30.7
 [root@all-node ~]# nerdctl pull docker.io/calico/kube-controllers:v3.30.7
部署 calico 网络
 #执行后:集群会在 kube-system 命名空间创建 calico-node(每个节点运行 1 个)、calico-kube-controllers 控制器
 [root@master30 ~]# kubectl apply -f calico.yaml
验证部署
 [root@master30 ~ 21:20:09]# kubectl  get pods --all-namespaces 
 NAMESPACE     NAME                                         READY   STATUS    RESTARTS   AGE
 kube-system   calico-kube-controllers-56fcbf9d6b-v6qsn     1/1     Running   0          28m
 kube-system   calico-node-vc9v6                            1/1     Running   0          28m
 kube-system   coredns-6d8c4cb4d-9qdxg                      1/1     Running   0          43m
 kube-system   coredns-6d8c4cb4d-wwfmx                      1/1     Running   0          43m
 kube-system   etcd-master30.laoma.cloud                    1/1     Running   0          43m
 kube-system   kube-apiserver-master30.laoma.cloud          1/1     Running   0          43m
 kube-system   kube-controller-manager-master30.laoma.cloud 1/1     Running   0          43m
 kube-system   kube-proxy-8b7tn                             1/1     Running   0          43m
 kube-system   kube-scheduler-master30.laoma.cloud          1/1     Running   0          43m

节点加入集群

 # 节点 worker31 加入集群
 [root@worker31 ~]# kubeadm join 10.1.8.30:6443 --token mi0yt8.1tzza4q64dr8y3pc \
     --discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd
 [preflight] Running pre-flight checks
     [WARNING SystemVerification]: missing optional cgroups: blkio
 [preflight] Reading configuration from the cluster...
 [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
 [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
 [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
 [kubelet-start] Starting the kubelet
 [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
 ​
 This node has joined the cluster:
 * Certificate signing request was sent to apiserver and a response was received.
 * The Kubelet was informed of the new secure connection details.
 ​
 Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
 ​
 # 节点 worker32 加入集群
 [root@worker32 ~]# kubeadm join 10.1.8.30:6443 --token mi0yt8.1tzza4q64dr8y3pc \
     --discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd

如果没有保存初始化界面中加入集群命令,可以通过以下命令获取加入集群命令:

[root@master30 ~]# kubeadm token create --print-join-command
kubeadm join 10.1.8.30:6443 --token dzpuca.8lqxqqydwskroabx --discovery-token-ca-cert-hash sha256:5606e09618330aee8859abe3ea4cd8734f9b540630048a6e1c3aaf6c54d486fd

验证部署

# 查看集群信息
[root@master30 ~ 21:21:08]# kubectl  cluster-info 
Kubernetes control plane is running at https://10.1.8.30:6443
CoreDNS is running at https://10.1.8.30:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.


# 查看版本,正常要求:客户端和服务端大版本保持一致
[root@master30 ~ 21:26:52]# kubectl version 
Client Version: v1.30.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.30.2

#Client Version:本机 kubectl 工具版本
#Server Version:集群 apiserver 真实版本


# 查看节点状态
[root@master30 ~ 21:27:10]# kubectl  get nodes
NAME                STATUS   ROLES           AGE   VERSION
master30.zy.cloud   Ready    control-plane   11d   v1.30.2
worker31.zy.cloud   Ready    <none>          11d   v1.30.2
worker32.zy.cloud   Ready    <none>          11d   v1.30.2


输出字段说明:
NAME:节点主机名
STATUS:节点状态
   *Ready:满足四大条件(Calico 网络就绪、kubelet 正常运行、swap 关闭、selinux 关闭)
   *NotReady:网络插件异常 /kubelet 挂了
ROLES:角色,master 带 control-plane,worker 无角色
AGE:节点加入集群时长
VERSION:节点 kubelet 版本

节点的状态为 Ready,必须满足以下条件:

  • 网络配置完成

  • 节点启动 kubelet 服务

  • swap 关闭

  • SELinux 关闭

 # 查看 pod 状态
 #-A 等价 --all-namespaces,相当于kubectl get pods --all-namespace
 [root@master30 ~ 21:28:47]# kubectl  get pods -A
 NAMESPACE     NAME                                          READY   STATUS    RESTARTS   AGE
 kube-system   calico-kube-controllers-7cb4fd5784-jx2xl      1/1     Running   0          11m
 kube-system   calico-node-4b6s8                             1/1     Running   0          11m
 kube-system   calico-node-bsr7v                             1/1     Running   0          11m
 kube-system   calico-node-v8jdn                             1/1     Running   0          11m
 kube-system   coredns-66f779496c-4j88h                      1/1     Running   0          13m
 kube-system   coredns-66f779496c-fnb8m                      1/1     Running   0          13m
 kube-system   etcd-master30.laoma.cloud                     1/1     Running   0          13m
 kube-system   kube-apiserver-master30.laoma.cloud           1/1     Running   0          13m
 kube-system   kube-controller-manager-master30.laoma.cloud  1/1     Running   0          13m
 kube-system   kube-proxy-27vl2                              1/1     Running   0          11m
 kube-system   kube-proxy-npv9h                              1/1     Running   0          11m
 kube-system   kube-proxy-q2qrs                              1/1     Running   0          11m
 kube-system   kube-scheduler-master30.laoma.cloud           1/1     Running   0          13m

Node and Cluster

学习参考:Node

查看节点

 # 查看节点清单
 [root@master30 ~ 21:09:19]# kubectl  get nodes
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   11d   v1.30.2
 worker31.zy.cloud   Ready    <none>          11d   v1.30.2
 worker32.zy.cloud   Ready    <none>          11d   v1.30.2
 ​
 # 查看特定节点详细信息
 #describe:查看资源完整详情:输出包含:节点 IP、系统资源、标签、污点、运行 Pod、事件、内存 CPU 压力、网络信息等
 #用途:节点异常(NotReady、资源不足)排错核心命令
 [root@master30 ~ 21:10:18]# kubectl  describe  nodes worker31.zy.cloud 
 ​

删除节点

以 worker31 节点为例。

 # 设置节点为维护模式
 #核心作用:驱逐节点上所有业务 Pod,并封锁节点,禁止新 Pod 调度上来(维护模式)
 [root@master30 ~ 21:54:32]# kubectl  drain  worker31.zy.cloud  --ignore-daemonsets 
 node/worker31.zy.cloud cordoned
 Warning: ignoring DaemonSet-managed Pods: kube-system/calico-node-x27nl, kube-system/kube-proxy-mb7vn
 node/worker31.zy.cloud drained
 ​
 参数拆解:
 drain:排空节点,驱逐普通 Deployment/StatefulSet 等 Pod 到其他可用节点
 --ignore-daemonsets:忽略 DaemonSet 控制器管理的 Pod(calico-node、kube-proxy 每个节点必须运行,无法驱逐,不加该参数会命令报错)
 ​
 ​
 #节点增加状态标记 SchedulingDisabled
 #普通 Pod 全部被驱逐至其他健康节点,保证业务不中断
 [root@master30 ~ 21:36:11]# kubectl  get nodes
 NAME                STATUS                     ROLES           AGE   VERSION
 master30.zy.cloud   Ready                      control-plane   11d   v1.30.2
 worker31.zy.cloud   Ready,SchedulingDisabled   <none>          11d   v1.30.2
 worker32.zy.cloud   Ready                      <none>          11d   v1.30.2
 ​
 ​
 # 删除 worker31 节点
 #在Master 节点执行,从 K8s 集群 API 中移除该节点记录
 #注意:仅删除集群层面的注册信息,不会清理 worker 本机 K8s 组件,本机 kubelet、证书、配置文件依然存在
 [root@master30 ~ 21:38:21]# kubectl  delete  nodes worker31.zy.cloud 
 node "worker31.zy.cloud" deleted
 ​
 ​
 [root@master30 ~ 21:38:57]# kubectl  get nodes
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   11d   v1.30.2
 worker32.zy.cloud   Ready    <none>          11d   v1.30.2
 ​
 ​
 # 重置删除的 worker31 节点,!!!kubeadm reset 严禁在 master 随意执行,执行即销毁集群;
 [root@worker31 ~ 21:50:57]# kubeadm reset -f
 [preflight] Running pre-flight checks
 W0704 21:55:37.381152    4098 removeetcdmember.go:106] [reset] No kubeadm config, using etcd pod spec to get data directory
 [reset] Deleted contents of the etcd data directory: /var/lib/etcd
 [reset] Stopping the kubelet service
 [reset] Unmounting mounted directories in "/var/lib/kubelet"
 [reset] Deleting contents of directories: [/etc/kubernetes/manifests /var/lib/kubelet /etc/kubernetes/pki]
 [reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf]
 ​
 The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d
 ​
 The reset process does not reset or clean up iptables rules or IPVS tables.
 If you wish to reset iptables, you must do so manually by using the "iptables" command.
 ​
 If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar)
 to reset your system's IPVS tables.
 ​
 The reset process does not clean your kubeconfig files and you must remove them manually.
 ​
 ​
 自动清理内容
 停止 kubelet 服务
 清空 etcd 数据目录(worker 无 etcd,仅 master 生效)
 删除证书目录 /etc/kubernetes/pki
 删除各类 kubeadm 静态 Pod 清单、kubelet 配置
 清除集群相关 admin.conf、kubelet.conf 等凭证文件
 ​

Kubernetes集群Worker节点重新加入与新增流程

一、把已删除的 worker31 重新加入集群完整流程

(1)登录 worker31 机器,彻底清理旧集群残留(必须执行,否则加入冲突)

清空 Calico 网络配置、iptables/ipvs 转发规则、所有旧 K8s 证书与 kubelet 数据,彻底消除旧集群残留冲突,是重入节点必须步骤。

 [root@worker31 ~ 21:56:53]# rm -rf /etc/cni/net.d/*
 [root@worker31 ~ 21:57:02]# iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
 [root@worker31 ~ 21:57:06]# ipvsadm --clear
 [root@worker31 ~ 21:57:09]# rm -rf /etc/kubernetes/* /var/lib/kubelet/* $HOME/.kube
 ​
(2)master 生成节点加入指令
 [root@master30 ~ 21:55:29]# kubeadm token create --print-join-command
 kubeadm join 10.1.8.30:6443 --token oct426.obhmlv6kmhpkivji --discovery-token-ca-cert-hash sha256:ffc65c9fa26b5abddd73867ac6da4d20c613af9cdb1831201018f24d6842f240 
 ​

复制输出的 kubeadm join xxx 整条命令

(3)worker31 执行 join 命令重新加入集群

粘贴上一步复制的 join 命令运行

 [root@worker31 ~ 21:57:13]# kubeadm join 10.1.8.30:6443 --token oct426.obhmlv6kmhpkivji --discovery-token-ca-cert-hash sha256:ffc65c9fa26b5abddd73867ac6da4d20c613af9cdb1831201018f24d6842f240 
 [preflight] Running pre-flight checks
 [preflight] Reading configuration from the cluster...
 [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
 [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
 [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
 [kubelet-start] Starting the kubelet
 [kubelet-check] Waiting for a healthy kubelet. This can take up to 4m0s
 [kubelet-check] The kubelet is healthy after 501.470642ms
 [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap
 ​
 This node has joined the cluster:
 * Certificate signing request was sent to apiserver and a response was received.
 * The Kubelet was informed of the new secure connection details.
 ​
 Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
 ​
(4)master 验证节点就绪
 [root@master30 ~ 21:57:19]# kubectl get nodes
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   12d   v1.30.2
 worker31.zy.cloud   Ready    <none>          8s    v1.30.2
 worker32.zy.cloud   Ready    <none>          11d   v1.30.2

二、新增其他全新 worker 节点(比如 worker33)流程

  1. 新节点提前完成环境准备:关闭 swap、关闭 SELinux、安装 containerd、kubeadm/kubelet/kubectl 同版本

  2. master 获取加入命令

 [root@master30 ~ 22:18:00]# kubeadm token create --print-join-command
 kubeadm join 10.1.8.30:6443 --token wqf9x1.dldk1ja0jfp3l33f --discovery-token-ca-cert-hash sha256:ffc65c9fa26b5abddd73867ac6da4d20c613af9cdb1831201018f24d6842f240 
 ​
  1. 在新 worker 节点执行这条 join 命令

     [root@worker33 ~ 22:16:19]# kubeadm join 10.1.8.30:6443 --token wqf9x1.dldk1ja0jfp3l33f --discovery-token-ca-cert-hash sha256:ffc65c9fa26b5abddd73867ac6da4d20c613af9cdb1831201018f24d6842f240 
     [preflight] Running pre-flight checks
     [preflight] Reading configuration from the cluster...
     [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
     [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
     [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
     [kubelet-start] Starting the kubelet
     [kubelet-check] Waiting for a healthy kubelet. This can take up to 4m0s
     [kubelet-check] The kubelet is healthy after 502.497346ms
     [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap
     ​
     This node has joined the cluster:
     * Certificate signing request was sent to apiserver and a response was received.
     * The Kubelet was informed of the new secure connection details.
     ​
     Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

  2. master 查看节点状态确认 Ready

 [root@master30 ~ 22:18:04]# kubectl  get  nodes 
 NAME                STATUS     ROLES           AGE   VERSION
 master30.zy.cloud   Ready      control-plane   12d   v1.30.2
 worker31.zy.cloud   NotReady   <none>          21m   v1.30.2
 worker32.zy.cloud   NotReady   <none>          11d   v1.30.2
 worker33.zy.cloud   NotReady   <none>          8s    v1.30.2
 ​
 #33节点成功加入集群中

补充:token 过期手动生成永久有效令牌

 # 创建永不过期token
 kubeadm token create --ttl 0
 # 单独获取CA哈希值(手动拼接join用)
 openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

删除集群

删除集群流程:

  1. 删除所有 node

  2. 删除所有 master

整体逻辑 删集群分两大阶段:先清理所有 Worker 工作节点 → 再清理 Master 主节点; 清理完所有节点后,再重新初始化 Master、安装网络、让 Worker 重新加入集群。

具体步骤:

  1. 删除所有node节点

 [root@master30 ~ 10:04:27]# kubectl  drain worker31.zy.cloud --ignore-daemonsets  --force 
 node/worker31.zy.cloud cordoned
 Warning: ignoring DaemonSet-managed Pods: kube-system/calico-node-mg2xk, kube-system/kube-proxy-2sjhc
 node/worker31.zy.cloud drained
 [root@master30 ~ 20:53:06]# kubectl  drain worker32.zy.cloud --ignore-daemonsets  --force 
 node/worker32.zy.cloud cordoned
 Warning: ignoring DaemonSet-managed Pods: kube-system/calico-node-hmhp5, kube-system/kube-proxy-bj5j8
 node/worker32.zy.cloud drained
 [root@master30 ~ 20:53:13]# kubectl  delete  nodes  worker31.zy.cloud worker32.zy.cloud 
 node "worker31.zy.cloud" deleted
 node "worker32.zy.cloud" deleted
 ​
 ​
 #参数解释
 drain:排水、驱逐,把当前节点上运行的所有业务 Pod 全部赶到其他正常节点运行,保证业务不中断;
 --ignore-daemonsets:DaemonSet 类型 Pod(日志、监控这类每个节点必须跑一个的组件)不能被驱逐,忽略报错强制执行;
 --force:节点上有不受控制器管理的独立 Pod 时,强制驱逐。
 作用:先腾空节点,再删除节点,避免业务直接中断。
 ​
 ​
 # 重置节点,注意执行位置
 [root@worker31 ~ 10:02:48]# kubeadm  reset  -f 
 [root@worker32 ~ 20:47:56]# kubeadm   reset  -f 
 [preflight] Running pre-flight checks
 W0705 20:54:12.853746  200389 removeetcdmember.go:106] [reset] No kubeadm config, using etcd pod spec to get data directory
 [reset] Deleted contents of the etcd data directory: /var/lib/etcd
 [reset] Stopping the kubelet service
 [reset] Unmounting mounted directories in "/var/lib/kubelet"
 [reset] Deleting contents of directories: [/etc/kubernetes/manifests /var/lib/kubelet /etc/kubernetes/pki]
 [reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf]
 ​
 The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d
 ​
 The reset process does not reset or clean up iptables rules or IPVS tables.
 If you wish to reset iptables, you must do so manually by using the "iptables" command.
 ​
 If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar)
 to reset your system's IPVS tables.
 ​
 The reset process does not clean your kubeconfig files and you must remove them manually.
 Please, check the contents of the $HOME/.kube/config file.
 ​
 ​
 #-f:强制重置,不用手动确认
 #功能:删除节点上所有 K8s 配置、证书、容器数据、kubelet 配置,把机器恢复成未加入集群的干净状态。
  1. 删除master节点

 # 删除集群前获取集群配置;集群初始化参数都存在 kube-system 命名空间的 ConfigMap kubeadm-config,导出保存,后面重建集群直接复用,不用手动敲一堆参数。
 [root@master30 ~ 20:53:27]# kubectl  get cm kubeadm-config -n kube-system  -o yaml > kubeadm.yaml
 [root@master30 ~ 20:58:12]# cat kubeadm.yaml 
 apiVersion: v1
 data:
   ClusterConfiguration: |
     apiServer:
       timeoutForControlPlane: 4m0s
     apiVersion: kubeadm.k8s.io/v1beta3
     certificatesDir: /etc/kubernetes/pki
     clusterName: kubernetes
     controllerManager: {}
     dns: {}
     etcd:
       local:
         dataDir: /var/lib/etcd
     imageRepository: registry.k8s.io
     kind: ClusterConfiguration
     kubernetesVersion: v1.30.2
     networking:
       dnsDomain: cluster.local
       podSubnet: 10.224.0.0/16
       serviceSubnet: 10.96.0.0/12
     scheduler: {}
 kind: ConfigMap
 metadata:
   creationTimestamp: "2026-06-22T08:32:49Z"
   name: kubeadm-config
   namespace: kube-system
   resourceVersion: "240"
   uid: 7d836ab2-0014-4372-8480-8d1a822663a0
 ​
 ​
 ​
 ​
 ​
 # 修改kubeadm.yml内容如下:
 [root@master30 ~ 20:58:17]# vim kubeadm.yaml 
 # 删除1-3和22-28行,效果如下
 apiServer:
   timeoutForControlPlane: 4m0s
 apiVersion: kubeadm.k8s.io/v1beta3
 certificatesDir: /etc/kubernetes/pki
 clusterName: kubernetes
 controllerManager: {}
 dns: {}
 etcd:
   local:
     dataDir: /var/lib/etcd
 imageRepository: registry.k8s.io
 kind: ClusterConfiguration
 kubernetesVersion: v1.30.2
 networking:
   dnsDomain: cluster.local
   podSubnet: 10.224.0.0/16
   serviceSubnet: 10.96.0.0/12
 scheduler: {}
 ​
 [root@master30 ~ 20:59:33]# kubectl  delete  nodes  master30.zy.cloud 
 node "master30.zy.cloud" deleted
 [root@master30 ~ 21:00:31]# kubeadm  reset  -f
 #.kube/config 是 kubectl 连接集群的身份凭证,旧集群作废,直接删除,避免后续命令混淆。
 [root@master30 ~ 21:00:42]# rm -rf .kube/
 ​

重建集群

 #1. kubeadm init 初始化控制平面(二选一)
 #方式 1:使用刚才备份好的配置文件(推荐,参数统一不踩坑)
 [root@master30 ~ 21:01:09]# kubeadm  init  --config kubeadm.yaml (我选的是这个方式)
 -------------------------------------------------
 Then you can join any number of worker nodes by running the following on each as root:
 ​
 kubeadm join 10.1.8.30:6443 --token matqxu.hw34ycwln6eai0n1 \
     --discovery-token-ca-cert-hash sha256:6b6f772a87d94273574a4b49332df4b2b2c816ccee2635eb65b1e36484897164  #(worker节点加入集群的命令)
 ​
 ​
 ​
 ​
 #方式 2:手动指定版本与 Pod 网段
 [root@master30 ~]# kubeadm init --kubernetes-version=v1.30.2 --pod-network-cidr=10.224.0.0/16
 ​
 执行后会输出:apiserver 地址、join 令牌、CA 证书哈希,用于 Worker 加入集群。
 ​
 ​
 # 配置普通用户 kubectl 访问权限置凭据:意思是把集群管理员的身份证书复制到当前用户专属目录,并修改权限,让当前用户拥有集群管理员权限,无需 sudo 即可操作集群。
 [root@master30 ~ 21:03:24]# mkdir  -p $HOME/.kube
 [root@master30 ~ 21:05:41]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 [root@master30 ~ 21:06:07]# sudo chown  $(id -u):$(id -g) $HOME/.kube/config 
 ​
 ​
 /etc/kubernetes/admin.conf:集群最高管理员证书,只有 root 可读;
 复制到当前用户家目录 .kube/config,普通用户不用 sudo 就能执行 kubectl;
 chown 修改文件归属为当前登录用户,否则会权限不足。
 ​
 ​
 #一、为什么要 配置普通用户 kubectl 访问权限置凭据
 kubectl 是操作 K8s 集群的命令工具,它访问集群 kube-apiserver 需要身份证书,证明你是管理员。
 集群初始化后,管理员证书文件放在这里:
 /etc/kubernetes/admin.conf
 这是集群最高权限凭证,只有 root 用户能读取。
 下面三条命令,就是把这份管理员证书复制到普通用户目录,让你不用 sudo 就能直接敲 kubectl:
 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 sudo chown $(id -u):$(id -g) $HOME/.kube/config
 生成的文件:~/.kube/config,行业内统称 kubeconfig 管理员凭证文件。
 ​
 #二、为什么必须配置
 1. 不配置的后果
 直接执行 kubectl get nodes 会报错:
 要么提示找不到 .kube/config;
 要么权限不足,必须加 sudo kubectl get nodes。
 每次操作都加 sudo 很麻烦,而且脚本、自动化工具不方便使用。
 2. 文件权限限制
 /etc/kubernetes/admin.conf 归属 root,普通用户读取不了,直接用会鉴权失败。
 把它复制到自己家目录,再修改文件属主为当前登录用户,普通用户就能正常读取证书。
 3. 作用原理
 kubectl 默认会自动读取 ~/.kube/config,里面包含:
 apiserver 集群地址
 CA 根证书
 管理员客户端证书、私钥
 每次执行 kubectl 命令,都会带着这份证书去和 apiserver 做 TLS 加密身份校验,集群识别你是管理员,才允许增删改查所有资源。
 4. 一句话总结含义
 把集群管理员的身份证书复制到当前用户专属目录,并修改权限,让当前用户拥有集群管理员权限,无需 sudo 即可操作集群。
 #比如我做实验验证:
 [root@master30 ~ 21:19:47]# cd .kube/
 [root@master30 .kube 21:19:59]# ls
 cache  config
 [root@master30 .kube 21:19:59]# cd
 #把.kube/config移走到当前目录下
 [root@master30 ~ 21:20:10]# mv  .kube/config   .
 [root@master30 ~ 21:20:25]# ls
 calico.yaml  config  kubeadm.yaml
 #验证kubectl命令是否可以使用,发现不行
 [root@master30 ~ 21:20:26]# kubectl  get  nodes
 E0705 21:20:36.901546  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.901874  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.907567  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.907748  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:36.909579  366922 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 The connection to the server localhost:8080 was refused - did you specify the right host or port?
 [root@master30 ~ 21:20:36]# kubectl  get  pods
 E0705 21:20:43.463915  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.464846  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.466617  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.466831  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 E0705 21:20:43.468341  367020 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
 The connection to the server localhost:8080 was refused - did you specify the right host or port?
 #把config文件再移回到.kube/config
 [root@master30 ~ 21:20:43]# mv config  .kube/
 #发现kubectl命令可以执行
 [root@master30 ~ 21:20:55]# kubectl  get  pods
 No resources found in default namespace.
 [root@master30 ~ 21:20:59]# kubectl  get  nodes
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   17m   v1.30.2
 worker31.zy.cloud   Ready    <none>          11m   v1.30.2
 worker32.zy.cloud   Ready    <none>          10m   v1.30.2
 ​
 ​
 ​
 ​
 ​
 ​
 # 配置网络
 [root@master30 ~ 21:06:50]# kubectl  apply  -f  calico.yaml 
 ​
 ​
 # 加入集群
 [root@worker31 ~ 21:08:40]# kubeadm join 10.1.8.30:6443 --token matqxu.hw34ycwln6eai0n1 \
         --discovery-token-ca-cert-hash sha256:6b6f772a87d94273574a4b49332df4b2b2c816ccee2635eb65b1e36484897164
 [preflight] Running pre-flight checks
 [preflight] Reading configuration from the cluster...
 [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
 [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
 [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
 [kubelet-start] Starting the kubelet
 [kubelet-check] Waiting for a healthy kubelet. This can take up to 4m0s
 [kubelet-check] The kubelet is healthy after 501.572577ms
 [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap
 ​
 This node has joined the cluster:
 * Certificate signing request was sent to apiserver and a response was received.
 * The Kubelet was informed of the new secure connection details.
 ​
 Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
 ​
 [root@worker32 ~ 21:09:46]# kubeadm join 10.1.8.30:6443 --token matqxu.hw34ycwln6eai0n1 \
         --discovery-token-ca-cert-hash sha256:6b6f772a87d94273574a4b49332df4b2b2c816ccee2635eb65b1e36484897164
 [preflight] Running pre-flight checks
 [preflight] Reading configuration from the cluster...
 [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
 [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
 [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
 [kubelet-start] Starting the kubelet
 [kubelet-check] Waiting for a healthy kubelet. This can take up to 4m0s
 [kubelet-check] The kubelet is healthy after 503.260095ms
 [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap
 ​
 This node has joined the cluster:
 * Certificate signing request was sent to apiserver and a response was received.
 * The Kubelet was informed of the new secure connection details.
 ​
 Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
 ​

Namespace and Contexts

学习参考:Namespace

Namespace 介绍

 超通俗大白话讲解 Namespace(命名空间)
 类比先看懂
 一整套 K8s 集群 = 一栋超大共享写字楼
 Namespace = 写字楼里独立上锁的办公室隔间
 整栋楼的水电、电梯、场地(服务器 CPU / 内存 / 磁盘)所有人共用,但隔间互相隔开:A 团队在 1 号隔间办公、B 团队在 2 号隔间,互不干扰。
 ​
 Namespace 4 个核心用途,全是企业真实用法
 1、解决资源重名冲突(最基础作用)
 同一个集群里,不能出现两个一模一样名字的业务容器,不分隔间直接报错。
 举例子:
 开发团队、测试团队都需要部署一个 nginx 服务。
 不划分 Namespace:集群里只能有 1 个 nginx,开发、测试抢名字,部署失败;
 划分 2 个 ns:ns-dev、ns-test
 开发的 nginx 放在 ns-dev,测试的 nginx 放在 ns-test,同名完全不冲突,各自独立运行。
 2、逻辑隔离环境,把测试和生产拆开(企业高频)
 很多公司资源有限,只用一套集群,靠 Namespace 区分环境,不用多搭整套集群:
 ns-test:开发随便造 bug、删服务、压测,随便折腾;
 ns-prod:线上真实用户业务,严格管控操作;
 哪怕共用底层服务器硬件,两套业务逻辑完全隔离,开发误删容器不会影响线上。
 补充:这只是逻辑隔离,如果需要彻底物理隔离(防止测试程序占满服务器拖垮生产),才会搭建两套独立集群(切换 context 那种)。
 3、给不同隔间限制资源上限,防止一人占满全部机器
 可以给每个 Namespace 设置资源配额(CPU、内存最大使用量):
 给测试隔间 ns-test 限制最多只能用 2 核 4G 内存。
 哪怕开发写了死循环程序疯狂吃资源,最多只占用测试隔间配额,不会抢光生产业务的服务器资源,线上服务不会卡顿崩溃。
 4、精细化权限管控,限制人员操作范围
 给员工分配隔间钥匙:
 普通开发:只拥有 ns-test 读写权限,只能操作测试命名空间,看不到、改不了 ns-prod 线上业务;
 运维管理员:拥有所有 Namespace 全部权限,能操作测试、预发、生产所有隔间;
 从根源避免开发手滑删线上服务。
 5、简化 kubectl 命令,不用每次输长参数
 你之前 kubeconfig 里配置了 namespace: default,就是默认隔间:
 执行 kubectl get pods,自动查询 default 命名空间;
 不加 -n 名字 就不用手动指定隔间,减少重复输入。
 区分两个容易搞混的概念:Context vs Namespace
 切换 Context = 换一整栋写字楼(切换整套独立集群,机器硬件完全分开)
 切换 Namespace = 同一栋写字楼里,换不同办公室隔间(同一集群内逻辑分组)
 ​
 #设置某个命名空间ns为默认命名空间
 kubectl config set-context --current --namespace=名字空间名
 ​
 #查看当前集群所在的命名空间的命令:
 #方式1.最简命令(直接看当前默认 ns)
 [root@master30 ~ 21:31:10]# kubectl config view --minify | grep namespace
 #方式2.表格中 NAMESPACE 列对应当前集群默认命名空间,* 标记的行是正在使用的集群上下文。
 [root@master30 ~ 21:31:18]# kubectl config get-contexts
 CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
 *         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   
 ​
 输出里 NAMESPACE 那一栏是空的,且 grep 没搜到 namespace 字段,代表:
 当前上下文没有手动设置过默认命名空间,Kubernetes 会自动使用内置默认命名空间 default。
 ​
 ​
 ​
 ​
 ​
 [root@master30 ~ 21:31:22]# kubectl  create  ns zy
 namespace/zy created
 [root@master30 ~ 21:33:25]# kubectl  get  ns
 NAME              STATUS   AGE
 default           Active   30m
 kube-node-lease   Active   30m
 kube-public       Active   30m
 kube-system       Active   30m
 zy                Active   6s
 [root@master30 ~ 21:34:14]# kubectl config view --minify | grep namespace
     namespace: zy
 #设置某个命名空间ns为默认命名空间:kubectl config set-context --current --namespace=名字空间名
 [root@master30 ~ 21:33:31]# kubectl  config  set-context  --current --namespace=zy
 Context "kubernetes-admin@kubernetes" modified.  
 [root@master30 ~ 21:33:54]# kubectl  config  get-contexts 
 CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
 *         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   zy
 ​
 ​

问题:多个用户使用同一个Kubernetes Cluster, 如何将他们创建的资源隔离开呢?

答案:Namespace,简写ns,也称之为 project,代表资源集合,用于分组集群资源。Kubernetes 使用 Namespace 可以将一个物理的 Cluster 逻辑上划分成多个资源集合, 每个集合就是一个Namespace。 不同Namespace 里的资源是完全隔离的。

Kubernetes 默认创建以下Namespace:

  • default: 创建资源时如果不指定Namespace, 将被放到这个Namespace中。

  • kube-system: Kubernetes 自己创建的系统资源将放到这个Namespace中。

  • kube-public:该命名空间中所有对象可以被所有用户(包括未验证身份的用户)读取。

  • kube-node-lease:该命名空间含有与每个节点关联的Lease对象。节点租用允许kubelet发送heartbeat(心跳),以便控制平面能检测节点故障。

思考:所有对象都属于 Namespace 吗?

答:大多数Kubernetes资源(例如 pod、services、pvc等)都属于某个Namespace,但 Namespace 资源本身并不在 Namespace 中,更低级别资源(如Node和persistentVolumes)也不在任何Namespace中。

Namespace 管理

 # 查看Namespace清单
 [root@master30 ~ 21:34:59]# kubectl  get  ns
 NAME              STATUS   AGE
 default           Active   45m
 kube-node-lease   Active   45m
 kube-public       Active   45m
 kube-system       Active   45m
 ​
 ​
 # 获取Namespace资源yaml格式定义文件
 [root@master30 ~ 21:48:23]# kubectl get ns default -o yaml
 apiVersion: v1
 kind: Namespace
 metadata:
   creationTimestamp: "2026-07-05T13:03:21Z"
   labels:
     kubernetes.io/metadata.name: default
   name: default
   resourceVersion: "26"
   uid: e1527aae-0d87-4465-944d-2057adc712fa
 spec:
   finalizers:
   - kubernetes
 status:
   phase: Active
 ​
 ​
 # 创建Namespace
 [root@master30 ~ 21:31:22]# kubectl  create  ns zy
 namespace/zy created
 ​
 # 注意:命名空间名称满足正则表达式[a-z0-9]([-a-z0-9]*[a-z0-9])?,最大长度为63位
 ​
 # 直接编辑Namespace
 [root@master30 ~ 21:48:34]# kubectl  edit  ns zy 
 Edit cancelled, no changes made.
 ​
 # 查看Namespace详细信息
 [root@master30 ~ 21:49:37]# kubectl  describe  ns zy 
 Name:         zy
 Labels:       kubernetes.io/metadata.name=zy
 Annotations:  <none>
 Status:       Active
 ​
 No resource quota.
 ​
 No LimitRange resource.
 ​
 ​
 # 删除Namespace
 [root@master30 ~ 21:49:51]# kubectl delete ns zy
 namespace "zy" deleted
 ​
 # 注意:
 # 删除一个namespace会自动删除该namespace中所有资源。
 # default和kube-system命名空间不可删除。

Namespace 还可以通过 yaml 文件创建。

 [root@master30 ~ 21:51:02]# vim ns-zy-yaml
 # ns-zy.yaml
 apiVersion: v1
 kind: Namespace
 metadata:
   name: zy
   
 [root@master30 ~ 21:51:02]# kubectl  apply -f  ns-zy.yaml 
 namespace/zy created

操作特定ns中对象,需要使用选项-n指定ns,例如:

 [root@master30 ~ 21:51:18]# kubectl  run  web --image=nginx -n zy
 pod/web created
 ​
 #-n 是 --namespace 的简写,指定命名空间。
 #-n zy:只查询 zy 这个命名空间 下的 Pod;不加 -n 的话,只会查当前默认命名空间(你这里是空配置,默认是 default)。
 [root@master30 ~ 21:51:52]# kubectl  get pod -n zy -o wide 
 NAME   READY   STATUS    RESTARTS   AGE   IP               NODE                NOMINATED NODE   READINESS GATES
 web    1/1     Running   0          19s   10.224.215.129   worker31.zy.cloud   <none>           <none>
 ​
 [root@master30 ~ 21:52:11]# curl -s 10.224.215.129 | grep   nginx
 <title>Welcome to nginx!</title>
 <h1>Welcome to nginx!</h1>
 <p>If you see this page, nginx is successfully installed and working.
 <a href="https://nginx.org/">nginx.org</a>.<br/>
 <a href="https://community.nginx.org/">community.nginx.org</a>.<br/>
 <a href="https://f5.com/nginx">f5.com/nginx</a>.</p>
 <p><em>Thank you for using nginx.</em></p>
 ​

Namespace 切换

kubectl

查看当前所在ns

 [root@master30 ~ 21:31:18]# kubectl config get-contexts
 CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
 *         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   
 ​

输出里 NAMESPACE 那一栏是空的,且 grep 没搜到 namespace 字段

代表:当前上下文没有手动设置过默认命名空间,Kubernetes 会自动使用内置默认命名空间 default。

设置默认ns

 [root@master30 ~ 21:52:36]# kubectl config set-context --current --namespace=zy
 Context "kubernetes-admin@kubernetes" modified.
 [root@master30 ~ 21:53:53]# kubectl config get-contexts 
 CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
 *         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   zy
 ​

此时,NAMESPACE 列对应的属性为 zy。

kubens

kubens 是第三方小工具,专门快速切换 / 查看 K8s 命名空间;

替代很长的原生命令:kubectl config set-context --current --namespace=xxx;

操作更简单,搭配 kubectx(切换集群上下文)一套使用。

kubens 安装

 [root@master30 ~ 21:53:58]# wget https://codeload.github.com/ahmetb/kubectx/zip/refs/heads/master -O kubectx.zip
 --2026-07-05 21:55:16--  https://codeload.github.com/ahmetb/kubectx/zip/refs/heads/master
 Resolving codeload.github.com (codeload.github.com)... 20.205.243.165
 Connecting to codeload.github.com (codeload.github.com)|20.205.243.165|:443... connected.
 HTTP request sent, awaiting response... 200 OK
 Length: unspecified [application/zip]
 Saving to: ‘kubectx.zip’
 ​
 kubectx.zip               [   <=>                  ] 566.81K  1.13MB/s    in 0.5s    
 ​
 2026-07-05 21:55:18 (1.13 MB/s) - ‘kubectx.zip’ saved [580417]
 ​
 [root@master30 ~ 21:55:26]# apt install  unzip 
 [root@master30 ~ 21:55:18]# ls
 calico.yaml  kubeadm.yaml  kubectx.zip  ns-zy.yaml
 ​
 [root@master30 ~ 21:55:43]# unzip kubectx.zip
 ​
 [root@master30 ~ 21:55:44]# ls kubectx-master/
 cmd         CONTRIBUTING.md  go.sum  internal  kubens   README.md
 completion  go.mod           img     kubectx   LICENSE  test
 ​
 #/usr/local/bin/:系统全局命令目录,放这里任意目录都能直接敲 kubens 调用
 [root@master30 ~ 21:55:49]# cp kubectx-master/kubens /usr/local/bin/
 #chmod +x:给脚本增加执行权限,不然运行会提示权限不足
 [root@master30 ~ 21:56:03]# chmod +x /usr/local/bin/kubens
 ​
 # 配置补全
 [root@master30 ~]# cp kubectx-master/completion/kubens.bash /etc/bash_completion.d/
 [root@master30 ~]# source /etc/bash_completion.d/kubens.bash

kubens 命令使用

 [root@master30 ~ 21:57:09]# kubens  -h
 Switch between Kubernetes namespaces.
 ​
 USAGE:
   kubens                    : list the namespaces in the current context
   kubens <NAME>             : change the active namespace of current context
   kubens -                  : switch to the previous namespace in this context
   kubens -c, --current      : show the current namespace
   kubens -h,--help          : show this message
 ​
   (This executable is the legacy bash-based implementation, consider upgrading to Go-based implementation.)
 ​
 #kubens 不带参数:列出集群所有命名空间
 [root@master30 ~ 21:57:17]# kubens 
 default
 kube-node-lease
 kube-public
 kube-system
 zy
 ​
 #kubens  命名空间名:永久切换默认命名空间
 #等价原生长命令:kubectl config set-context --current --namespace=kube-system
 [root@master30 ~ 21:57:29]# kubens  kube-system 
 Context "kubernetes-admin@kubernetes" modified.
 Active namespace is "kube-system".
 ​
 [root@master30 ~ 21:57:45]# kubectl  config  get-contexts 
 CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
 *         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   kube-system
 ​
 ​
 [root@master30 ~ 21:58:01]# kubectl get pods
 NAME                                        READY   STATUS    RESTARTS   AGE
 calico-kube-controllers-585df69d45-2cc6g    1/1     Running   0          50m
 calico-node-5l6qm                           1/1     Running   0          48m
 calico-node-6kjbg                           1/1     Running   0          50m
 calico-node-jpn9r                           1/1     Running   0          48m
 coredns-7db6d8ff4d-2vz26                    1/1     Running   0          54m
 coredns-7db6d8ff4d-rnkll                    1/1     Running   0          54m
 etcd-master30.zy.cloud                      1/1     Running   5          54m
 kube-apiserver-master30.zy.cloud            1/1     Running   5          54m
 kube-controller-manager-master30.zy.cloud   1/1     Running   5          54m
 kube-proxy-75d9b                            1/1     Running   0          48m
 kube-proxy-m2whw                            1/1     Running   0          54m
 kube-proxy-q5t56                            1/1     Running   0          48m
 kube-scheduler-master30.zy.cloud            1/1     Running   5          54m
 ​

自定义脚本

 #!/bin/bash
 function usage(){
   echo "$0 [namespace]
 1. 没有namespace参数时,显示namespace清单
 2. namespace必须是集群中存在的namespace"
 }
 ​
 # 获取当前namespace
 namespace=$(kubectl config get-contexts | awk '/\*/{print $5}')
 if [ -z "$namespace" ];then
   namespace=default
 fi
 ​
 # 显示 namespace清单
 if [ $# -eq 0 ];then
   kubectl get ns | awk '{print "  "$1}' | sed "s/^  $namespace/\* $namespace/"
   exit 1
 fi
 ​
 # 切换 namespace
 if [ $# -eq 1 ];then
   if kubectl get ns | awk '$1 !~ "NAME" {print $1}' | grep -qx "$1" &>/dev/null;then
     kubectl config set-context --current --namespace $1 > /dev/null
     echo "当前namespace设置为:$1"
   else
     usage  
   fi
 fi

Cluster 切换

~/.kube/config 详解

核心定位:kubectl 客户端唯一通信凭证文件 kubectl 是操作 K8s 集群的命令行工具,该文件存储全部「集群地址、安全证书、登录身份、切换快捷组合 ],没有它 kubectl 无法连接任何集群。

单集群配置

获取凭据文件内容(不显示敏感信息):

 [root@master30 ~ 08:45:03]# kubectl  config view 
 apiVersion: v1
 clusters:
 - cluster:
     certificate-authority-data: DATA+OMITTED
     server: https://10.1.8.30:6443
   name: kubernetes
 contexts:
 - context:
     cluster: kubernetes
     namespace: kube-system
     user: kubernetes-admin
   name: kubernetes-admin@kubernetes
 current-context: kubernetes-admin@kubernetes
 kind: Config
 preferences: {}
 users:
 - name: kubernetes-admin
   user:
     client-certificate-data: DATA+OMITTED
     client-key-data: DATA+OMITTED
 ​

配置文件示例:

 #从 cat ~/.kube/config 的输出里3 段字符串分别的作用:
 #certificate-authority-data(CA 根证书)
 #client-certificate-data(管理员证书)
 #client-key-data(管理员私钥)
 [root@master30 ~ 16:42:30]# cat ~/.kube/config 
 apiVersion: v1
 clusters:
 - cluster:
     certificate-authority-data:   LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJYzhPS2JKekVZdUF3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TmpBMk1qTXdOakU0TXpOYUZ3MHpOakEyTWpBd05qSXpNek5hTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUUMvU3hLREFKZGdXL3cyNTFWZ09zbmE3STg1cmQ4RzZnYWFUNmFRWVYxcDJYM2lkWXFVMEsrbzBGN0UKd2hpc3JhNHNtdXd0QjVMUlhiVlNQWldWZmVOTDU0R0NBT3NTQ2hoakV6TkhDZ25BdXlCZWZ0ZjIxQzBBdDk3Zgp6MDZVRzJCcmE3VmhaSkhFR3lwdExBZTRPUFVPSVNuNWQzNWJ5VzZsOXkwU1hJa0ZCV0cvQU1LMUFhaWFVL052CisxWC9HdmEySlZzQ0g2N29MNWRvWG8xcHdjK3VhVzNaaVZhNjRONHhPZFdVQ3JXRDJrakZjUjlCZWE4ZlovaTcKUnh2ODlURGE4S3A0SXlTUTkwZ215L3F2YUgxRGptTkV6WU9ReGE4VUVpdkx0VW52RUh6TjZMSC81anpJQVRDaQpDNStwbmlvR09zdFdKdmRBcnpqZUwxR2N1THpQQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJSdzFZWllCekF2VU1IeHJmbm1XL2ZFMUlQdVRUQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQlpHUzFud2g3QQpEdU1YaXlSd2ZFQ3RnVkVjeHpUVGFnWkROOW9UMjQ1Vmd0OEpNMGxtR1Nrbm5zbnVyRnMvZG96bnoxWmU3K255ClluTExyN3VzeXRzSE1PUFZ5VkJra3lBdWFxK0VhNWY0UHQ1NzJURVZFZzY1QzhTc042ajFEVlJDTURsZk95b1oKOGhIOU1PMGpaTnkwY3U1dFhzWXNRS2NuU1RUcmljbmcwdjVqaWJXU3lSU0pETkxQdm1UamM0Q1htaWZTdkJwSQplMVNKemRQZFpudTJsQUtvY21kSTVhZG5ISXUvdlhDOXdhMUVMMVk3aDdSaTQwa3RDQnhiRm5tSkxYZTVGM1gwCm8rNk02KzdHUXZRQ2RRb1laYVJ5MEc0MDhvWWZLaTg2VmtqcWdmWTFpWG5kZGJUYWhlVzIzcW1Bdm0rUnJBMFIKUkl5ZkRnSjc3cHliCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
     server: https://10.1.8.30:6443
   name: kubernetes
 contexts:
 - context:
     cluster: kubernetes
     namespace: kube-system
     user: kubernetes-admin
   name: kubernetes-admin@kubernetes
 current-context: kubernetes-admin@kubernetes
 kind: Config
 preferences: {}
 users:
 - name: kubernetes-admin
   user:
     client-certificate-data:               LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURLVENDQWhHZ0F3SUJBZ0lJWGpicmdQZ1ErUmN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TmpBMk1qTXdOakU0TXpOYUZ3MHlOekEyTWpNd05qSXpNelZhTUR3eApIekFkQmdOVkJBb1RGbXQxWW1WaFpHMDZZMngxYzNSbGNpMWhaRzFwYm5NeEdUQVhCZ05WQkFNVEVHdDFZbVZ5CmJtVjBaWE10WVdSdGFXNHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDeWhBakQKWndZTHZoU3J1N0tOWlhrdXFLZFhHL2Y1dUMzVnhMSEw2REtudWVpdzdDbTN4M0YzdUpaK09oWDJyMkRWZlMwRgpROVBTcjNOT21NRXliczA2enQ5NlJKMGgyUU1lZmFxT0lCVFlFZzN5TmlQVVVzWEt6N2k3dUdoTWNEVmJVUkt6Ck1PcEFDYnpyUUF6dUpEOXVXVVMzdmoxQlZHZmV5NTZvZGRTVTRMd01QUmxoWFhzcURqZXdVYjJlQVZaY1FtcDAKbUJTSlVTUFd0UTBabnBVUkFMT2pKa1g0TEl2M0lRR0p5UG5DYnd3LzJMbGRnMFNmcitiMlIyOWVqN3FHeDN0bgpiRGZOMEswY1M1SkRQbTBjUzJOWHlSbXRKdGg0OXJsV0pMQmEwSUZqdW5HZExaendIcW91TnpPVVVXVnU3VWxLClNKc2g4WENnSWpIQ1R3SEpBZ01CQUFHalZqQlVNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUsKQmdnckJnRUZCUWNEQWpBTUJnTlZIUk1CQWY4RUFqQUFNQjhHQTFVZEl3UVlNQmFBRkhEVmhsZ0hNQzlRd2ZHdAorZVpiOThUVWcrNU5NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUFxOVU4NDdiUnJMcUo0UWg4ajROR2pzeWV0CmR3alRiZUtmZDQ5Q3BaUHMwaTZGNWJKa3FmTlloTGxWNlZEZHM4MnA3T09DK3ovanJoZU16RGQ4Y0lYSHVGTHMKNUsyekNWOGd1citiUnJKUG5pbXplUE5PeU5mSHFNb1hBZnpJYm1JMkk4b0ZUOXVYb0VHM1NsZFRxZC9odExiZgpWRGZOZXhGUWhiVTFDd1M1ZE5xWmlZKytRVnRkcEdtak5JZjN1M3FNUTlGLy9mQUU2LzR6aWJRcXhKVGxSenphCmlndlZqdnF2WVBKVkFBZStpYlNKZ1RjUVBLcXQzU1U5NnZxSyt2S2JBcTR1ZG5iNEdnL3FpNHA5aEIyMFdjdkkKM08walJERDc5cnJzY281RUk4ZUVnRk9NRjFtdW4zbGMwbTUvc3RJZ1hnKzdsbkdhS1lHOXdFT1FGZnFZCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
     client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBc29RSXcyY0dDNzRVcTd1eWpXVjVMcWluVnh2MytiZ3QxY1N4eStneXA3bm9zT3dwCnQ4ZHhkN2lXZmpvVjlxOWcxWDB0QlVQVDBxOXpUcGpCTW03Tk9zN2Zla1NkSWRrREhuMnFqaUFVMkJJTjhqWWoKMUZMRnlzKzR1N2hvVEhBMVcxRVNzekRxUUFtODYwQU03aVEvYmxsRXQ3NDlRVlJuM3N1ZXFIWFVsT0M4REQwWgpZVjE3S2c0M3NGRzluZ0ZXWEVKcWRKZ1VpVkVqMXJVTkdaNlZFUUN6b3laRitDeUw5eUVCaWNqNXdtOE1QOWk1ClhZTkVuNi9tOWtkdlhvKzZoc2Q3WjJ3M3pkQ3RIRXVTUXo1dEhFdGpWOGtaclNiWWVQYTVWaVN3V3RDQlk3cHgKblMyYzhCNnFMamN6bEZGbGJ1MUpTa2liSWZGd29DSXh3azhCeVFJREFRQUJBb0lCQUZCMnV3eDRqMzBUZkhXNwo4TXRUQmNCR1BNZEMwQTg3T1UyMWp2NTk5dmNyRVB0T042K2lzajVvY1UwTUdZSkxvcllYNmdjSmY1empnSEhZCjRKdyszVHE0ckhxTUd0ZDYzYkVNcTZmTVJoanVhbUxXakdmVHQxdW5MWGxQc1pOaXNHb3NyT1VnRXpZeUxYbE0KTVlmVnh0R1NZeXIvRU5VMW1td09FOEdTK3ZMdmFEWEFhM3BsNTBSaGV1MGZYQWRRTGtJVlZkS01sYkVUNmdKcgpKVFM5L1RodHk3V1N1MFYxS205MVF6a0tZWS9XcWM1Nk1QWkJ1eUdhWW1leS9CTDU5dTBQTWpwdjJFVDVmRVU3ClA5UzkveTNUVkF1MFRpdzl1SzcrcGcvdi9MTlY3N0FWd2RBSkU4M1Fkak1wcmd0WWwyd1dXOWZ2Ky9aQ1E5VHAKellxWDVrRUNnWUVBeUhDaUE2anBzbnBDeFYxTzFkeElMcVlyajFma2NrS0tuWEsyaXBhcWJOLzRieE9OS0VPcApTbUx5VEtTZlA4bHljRndNTlM5ek56Qk1WRWZEMTV5V3pvYjNPTG9tREUyYVMrWkNMMVJzMFN0YmtNL2dLTXBGCjNxRjh1YmJDeGU4a0c5V2JLZThSZEVVQktocnVuU05ZWXFLNWZEbitYcWRmQ0VYZG5xZlk2KzBDZ1lFQTQvK2sKcEVYTnVZMlM4dWlKSnY4M2g1TWRyNG9WU0dCR1lIdFFTWmZDZHhvN09WWEJoeWRzUmpmeEhseEI3MFNXdjlQUgpnMDgyc1JmOFYwaGhHbTFmVncyRnZMZTVsSmo3aXV5TkkyMUxockZ4bDJhcHpNdWVucEFiZmpJOVg1ZjhwNEUvCnZwbUhXQkNjbE9DanBFeGc0S1dhM0RvWTZMV0VmU2lkRm1BeHljMENnWUExb2UyNERQcDdSenVXaytFRVdHejQKRG42WlhHdEVKNG52bDBKQTB3L0hFaWJua2RPemNtZGFBQi9WWWpjNldpekU0OXhnWHRIMWNuYjZGam5ROTVWaQpyYnA0ODFZNjlJalV4a2Z2WWllNzBGNHY0VytaZW9ZM2kvNVRzeE5xNHhKR1lHR2tWdFBVeUtJSElpMjIzajVJCkprSjdld2tWU3JPakF3N0o1UittQVFLQmdCdnNBT1BGVUs1NnNoWmhkL3A0b3ZwTmdBTXhhKzNUTEl0QVR0TFUKYlJKYytnZkpnc3ZrZmhRVFljb1FEbHNaRVVVbzBhMjlFN3VZYm1UYURscElMcmJnaHhKWGhiaTNDNGMxOVFyegpwWjQzT093THZKdkNEQWpyS1JMSllFN0d0RUJuU2NFejJDbG16MlpFSklaSWZFekd1ekpoUXcrc3V5OEF2RXd6Ck42VzVBb0dBTElscmRmSndoV0RLbkpYUC93L081cjZDY3FEaEVZank0NVdYWStPcURudkdDbTEvMGNtRFlBM3AKVlFMUHJlbGZ1aFpoTCtMM3JPNS9Xa3U0czVLNm9qazZQcXVwblovK3VMN29hQzhLM1BMVUEyMUF2ZkZ1UnUyVgplMysyd0QwSDdQekxFQkpFaHQ5RGpISTFBRkY2cUNEdkhwUWxDOWIzdnA3LzVnRDBXK009Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
     
     
 #三者证书关系总结:
 CA 根证书 = 集群根信任;
 client-cert = 管理员身份证件;
 client-key = 管理员证件配套私钥(保密,不可泄露)。

 #echo 长base64字符串 | base64 -d
 #功能:解码你 config 文件里 client-certificate-data 那串加密文本,还原出原始明文证书。
 #echo:输出那一大串 base64 编码文本
 #base64 -d:解码(-d = decode 解密)
 [root@master30 ~ 16:48:10]# echo LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJYzhPS2JKekVZdUF3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TmpBMk1qTXdOakU0TXpOYUZ3MHpOakEyTWpBd05qSXpNek5hTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUUMvU3hLREFKZGdXL3cyNTFWZ09zbmE3STg1cmQ4RzZnYWFUNmFRWVYxcDJYM2lkWXFVMEsrbzBGN0UKd2hpc3JhNHNtdXd0QjVMUlhiVlNQWldWZmVOTDU0R0NBT3NTQ2hoakV6TkhDZ25BdXlCZWZ0ZjIxQzBBdDk3Zgp6MDZVRzJCcmE3VmhaSkhFR3lwdExBZTRPUFVPSVNuNWQzNWJ5VzZsOXkwU1hJa0ZCV0cvQU1LMUFhaWFVL052CisxWC9HdmEySlZzQ0g2N29MNWRvWG8xcHdjK3VhVzNaaVZhNjRONHhPZFdVQ3JXRDJrakZjUjlCZWE4ZlovaTcKUnh2ODlURGE4S3A0SXlTUTkwZ215L3F2YUgxRGptTkV6WU9ReGE4VUVpdkx0VW52RUh6TjZMSC81anpJQVRDaQpDNStwbmlvR09zdFdKdmRBcnpqZUwxR2N1THpQQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJSdzFZWllCekF2VU1IeHJmbm1XL2ZFMUlQdVRUQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQlpHUzFud2g3QQpEdU1YaXlSd2ZFQ3RnVkVjeHpUVGFnWkROOW9UMjQ1Vmd0OEpNMGxtR1Nrbm5zbnVyRnMvZG96bnoxWmU3K255ClluTExyN3VzeXRzSE1PUFZ5VkJra3lBdWFxK0VhNWY0UHQ1NzJURVZFZzY1QzhTc042ajFEVlJDTURsZk95b1oKOGhIOU1PMGpaTnkwY3U1dFhzWXNRS2NuU1RUcmljbmcwdjVqaWJXU3lSU0pETkxQdm1UamM0Q1htaWZTdkJwSQplMVNKemRQZFpudTJsQUtvY21kSTVhZG5ISXUvdlhDOXdhMUVMMVk3aDdSaTQwa3RDQnhiRm5tSkxYZTVGM1gwCm8rNk02KzdHUXZRQ2RRb1laYVJ5MEc0MDhvWWZLaTg2VmtqcWdmWTFpWG5kZGJUYWhlVzIzcW1Bdm0rUnJBMFIKUkl5ZkRnSjc3cHliCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K  | base64 -d
 ​
 #输出的是解码后的文本
 -----BEGIN CERTIFICATE-----
 MIIDBTCCAe2gAwIBAgIIc8OKbJzEYuAwDQYJKoZIhvcNAQELBQAwFTETMBEGA1UE
 AxMKa3ViZXJuZXRlczAeFw0yNjA2MjMwNjE4MzNaFw0zNjA2MjAwNjIzMzNaMBUx
 EzARBgNVBAMTCmt1YmVybmV0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
 AoIBAQC/SxKDAJdgW/w251VgOsna7I85rd8G6gaaT6aQYV1p2X3idYqU0K+o0F7E
 whisra4smuwtB5LRXbVSPZWVfeNL54GCAOsSChhjEzNHCgnAuyBeftf21C0At97f
 z06UG2Bra7VhZJHEGyptLAe4OPUOISn5d35byW6l9y0SXIkFBWG/AMK1AaiaU/Nv
 +1X/Gva2JVsCH67oL5doXo1pwc+uaW3ZiVa64N4xOdWUCrWD2kjFcR9Bea8fZ/i7
 Rxv89TDa8Kp4IySQ90gmy/qvaH1DjmNEzYOQxa8UEivLtUnvEHzN6LH/5jzIATCi
 C5+pnioGOstWJvdArzjeL1GcuLzPAgMBAAGjWTBXMA4GA1UdDwEB/wQEAwICpDAP
 BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRw1YZYBzAvUMHxrfnmW/fE1IPuTTAV
 BgNVHREEDjAMggprdWJlcm5ldGVzMA0GCSqGSIb3DQEBCwUAA4IBAQBZGS1nwh7A
 DuMXiyRwfECtgVEcxzTTagZDN9oT245Vgt8JM0lmGSknnsnurFs/doznz1Ze7+ny
 YnLLr7usytsHMOPVyVBkkyAuaq+Ea5f4Pt572TEVEg65C8SsN6j1DVRCMDlfOyoZ
 8hH9MO0jZNy0cu5tXsYsQKcnSTTricng0v5jibWSyRSJDNLPvmTjc4CXmifSvBpI
 e1SJzdPdZnu2lAKocmdI5adnHIu/vXC9wa1EL1Y7h7Ri40ktCBxbFnmJLXe5F3X0
 o+6M6+7GQvQCdQoYZaRy0G408oYfKi86VkjqgfY1iXnddbTaheW23qmAvm+RrA0R
 RIyfDgJ77pyb
 -----END CERTIFICATE-------
 # 或者使用以下命令获取不显示具体证书和key内容
 [root@master30 ~]# kubectl config view
 apiVersion: v1
 clusters:
 - cluster:
     certificate-authority-data: DATA+OMITTED
     server: https://10.1.8.30:6443
   name: kubernetes
 contexts:
 - context:
     cluster: kubernetes
     user: kubernetes-admin
   name: kubernetes-admin@kubernetes
 current-context: kubernetes-admin@kubernetes
 kind: Config
 preferences: {}
 users:
 - name: kubernetes-admin
   user:
     client-certificate-data: REDACTED
     client-key-data: REDACTED

多集群配置

示例:/root/multi-cluster-config(自己创建的multi-cluster-config,这只是自定义临时配置文件名,不是系统固定文件名,你随便取名都行(比如 起名字叫two-cluster.yaml)文档只是统一用 multi-cluster-config 当示例。 作用:把两套集群完整连接信息写在这个独立文件里,不直接修改正在使用的 ~/.kube/config,避免改错导致当前集群连不上,方便测试、备份。)

 # 这是标准、完整、可直接使用的双集群 kubeconfig 模板(还可以扩展成多模板,再加其他集群就行。逻辑永远是:clusters 新增一段:集群地址 + 集群根 CA;users 新增一段:该集群专属用户证书;contexts 新增一段:绑定上面的 cluster名称 + user名称)
 apiVersion: v1
 ​
 # clusters 块:两套集群服务信息
 clusters:
 - cluster:
     certificate-authority-data: DATA+OMITTED # 集群1根CA证书base64完整字符串
     server: https://10.1.8.30:6443          # 第一套集群APIServer地址
   name: cluster1                            # 集群自定义名称
 - cluster:
     certificate-authority-data: DATA+OMITTED # 集群2独立根CA证书
     server: https://10.1.8.150:6443         # 第二套集群地址
   name: cluster2
 ​
 # contexts 上下文(绑定「集群 + 账号」,切换集群靠上下文)
 contexts:
 - context:
     cluster: cluster1        # 对应上方集群名称,必须一字不差匹配
     namespace: default       # 执行kubectl默认操作的命名空间,不需要可删除该行
     user: cluster1-admin     # 对应下方users块的账号名称
   name: cluster1-context     # 切换集群时使用的上下文名称
 - context:
     cluster: cluster2
     namespace: default
     user: cluster2-admin
   name: cluster2-context
 ​
 # current-context:kubectl默认加载的集群上下文
 current-context: cluster1-context    
 kind: Config
 preferences: {}
 ​
 # users 块:两套集群管理员凭证
 users:
 - name: cluster1-admin # 集群1管理员账号名
   user:
     client-certificate-data: DATA+OMITTED # 集群1 admin.crt base64编码
     client-key-data: DATA+OMITTED         # 集群1 admin.key base64编码
 - name: cluster2-admin # 集群2管理员账号(生产环境证书、私钥必须和集群1完全独立)
   user:
     client-certificate-data: DATA+OMITTED   # 集群2 admin.crt base64编码
     client-key-data: DATA+OMITTED           # 集群2 admin.key base64编码
 ​
 ​
 # 补充说明:
 # 1. 生产环境:两套集群必须使用各自master节点导出的独立CA、用户证书,不可复用
 # 2. 实验练习场景:可全部填充10.1.8.30集群证书,仅学习文件结构;切换cluster2会因150集群不存在报连接超时
 # 配套操作命令:
 # kubectl config get-contexts        # 查看全部集群上下文
 # kubectl config use-context xxx     # 切换指定集群
 # kubectl config current-context     # 查看当前默认集群
 ​
 ​
 ​
 ​
 ​
 ​
 ​
 #更详细解释:
 # ===================== 全局小白前置科普 =====================
 # 1、kubeconfig 是什么?
 #    kubectl 是操作K8s集群的命令工具,kubeconfig 就是 kubectl 的「通讯录+登录凭证」,
 #    没有这个文件,kubectl 不知道去哪连集群、用什么身份登录集群。
 # 2、本文件三大核心模块关系(大白话比喻):
 #    clusters:记录所有K8s集群的「服务器地址+集群身份证」,相当于门店地址
 #    users:记录登录集群的「个人账号+密码凭证」,相当于你的身份证
 #    contexts:快捷登录组合,把【门店地址(cluster)+你的身份证(user)】绑定在一起,
 #              切换集群 = 切换不同的context快捷组合,一键换集群不用改配置
 # 3、DATA+OMITTED 说明:这是占位符,需要删除,替换成crt/key文件转出来的一整行base64长文本
 # 4、两种使用场景区分:
 #    ① 生产真实环境:两个集群必须使用各自master节点导出的独立证书,不能混用
 #    ② 课堂实验学习:可以全部填同一套集群证书,仅用来学习文件结构,无法真实访问另一台不存在的集群
 ​
 ​
 ​
 ​
 # ==========================================================
 apiVersion: v1 # K8s配置文件固定版本号,所有集群统一v1,不许修改
 ​
 # ===================== clusters 集群信息块 =====================
 # 作用:存放你所有K8s集群的连接地址、集群根CA证书(用来校验集群真伪)
 clusters:
 # 第一套集群:master30 10.1.8.30
 - cluster:
     # certificate-authority-data:集群根CA证书,对应集群master节点 /root/.kube/ca.crt 文件
     # 作用:kubectl客户端校验目标集群APIServer的身份,防止伪装的假集群劫持你的操作
     # 替换方法:cat ca.crt | base64 -w 0  输出的完整字符串粘贴到此处,删除DATA+OMITTED
     certificate-authority-data: DATA+OMITTED
     # server:集群API服务固定访问地址,格式 https://master节点IP:6443
     # 所有kubectl增删改查资源的命令,都会通过这个地址和集群通信,端口6443是K8s默认固定端口
     server: https://10.1.8.30:6443
   # name:给当前这套集群自定义唯一名称,后面context上下文必须一字不差匹配这个名字,错一个字符都会报错
   name: cluster1
 ​
 # 第二套集群:虚拟集群10.1.8.150(实验环境无真实机器)
 - cluster:
     # 生产环境要求:必须使用10.1.8.150集群master导出的独立ca.crt证书,不能复用cluster1的证书
     # 实验练习可偷懒:直接粘贴cluster1的CA证书字符串,仅学习文件语法结构
     certificate-authority-data: DATA+OMITTED
     server: https://10.1.8.150:6443
   name: cluster2
 ​
 ​
 ​
 # ===================== contexts 快捷登录上下文块 =====================
 # 核心作用:绑定「集群名称(cluster) + 登录账号(user)」,生成一键切换的快捷登录配置
 # 每次切换集群只需要切换context,不用手动修改集群地址、账号凭证
 contexts:
 # 快捷配置1:连接cluster1集群,使用cluster1-admin账号登录
 - context:
     # cluster:关联上方clusters块内定义的集群名称,必须完全一致,大小写、字符不能有差异
     cluster: cluster1
     # namespace:默认命名空间,执行kubectl命令时不加 -n xxx 参数,默认操作这个命名空间
     # 如果你不需要默认命名空间,直接删除这一整行即可,不会影响配置运行
     namespace: default
     # user:关联下方users块内定义的账号名称,必须完全匹配,用来指定登录集群的身份
     user: cluster1-admin
   # name:这个快捷登录配置的自定义名称,切换集群命令 kubectl config use-context 后面跟这个名字
   name: cluster1-context
 ​
 # 快捷配置2:连接cluster2集群,使用cluster2-admin账号登录
 - context:
     cluster: cluster2
     namespace: default
     user: cluster2-admin
   name: cluster2-context
 ​
 # current-context:kubectl工具默认加载的快捷登录配置
 # 打开终端执行kubectl命令,不手动切换context时,自动使用这里写的上下文
 current-context: cluster1-context
 ​
 # 固定标识字段,所有kubeconfig文件统一写Config,不能修改
 kind: Config
 # 用户偏好设置,无特殊需求直接留空{},小白无需修改、不用填充内容
 preferences: {}
 ​
 ​
 ​
 # ===================== users 用户账号凭证块 =====================
 # 作用:存放登录集群的用户身份凭证(客户端证书+私钥),相当于登录集群的身份证和密钥
 # 生产环境:每个集群的账号证书完全独立,不可交叉复用
 users:
 # 账号1:cluster1集群管理员账号
 - name: cluster1-admin # 自定义账号名称,上方context里的user字段必须和这里完全一致
   user:
     # client-certificate-data:用户客户端证书,对应master节点 /root/.kube/admin.crt 文件
     # 作用:向集群证明你是合法管理员用户,集群校验你的身份权限
     # 转换命令:cat admin.crt | base64 -w 0  复制输出全部字符串替换占位符
     client-certificate-data: DATA+OMITTED
     # client-key-data:用户私钥文件,对应master节点 /root/.kube/admin.key
     # 作用:加密你和集群之间的通信,保证操作数据不被窃听、篡改
     client-key-data: DATA+OMITTED
 ​
 # 账号2:cluster2集群管理员账号
 - name: cluster2-admin
   user:
     # 生产环境强制要求:使用10.1.8.150集群导出的admin.crt、admin.key,和cluster1区分开
     # 实验学习可偷懒:直接复制cluster1的两段证书字符串,仅用来测试YAML语法不报错
     client-certificate-data: DATA+OMITTED
     client-key-data: DATA+OMITTED
 ​
 # ===================== 小白配套操作手册(必看) =====================
 # 一、证书占位符 DATA+OMITTED 替换完整步骤(复制执行命令)
 # 1、登录集群master节点,进入 /root/.kube 目录,拿到3个文件:ca.crt admin.crt admin.key
 # 2、转换无换行base64字符串(-w 0 作用:禁止自动换行,避免YAML解析报错)
 # cat ca.crt | base64 -w 0
 # cat admin.crt | base64 -w 0
 # cat admin.key | base64 -w 0
 # 3、复制命令输出的一长串字符,删除模板里 DATA+OMITTED,粘贴进去,不要换行!
 ​
 # 二、集群切换全套操作命令
 # 1、查看所有可用集群快捷上下文(查看你配置了几套集群)
 # kubectl config get-contexts
 # 2、切换到指定集群(替换xxx为context的name,例如cluster2-context)
 # kubectl config use-context xxx
 # 3、查看当前正在使用的集群上下文
 # kubectl config current-context
 # 4、验证集群连通性(切换后执行,正常输出节点代表配置生效)
 # kubectl get nodes
 ​
 # 三、小白高频报错避坑
 # 1、yaml: line x: could not find expected ':'
 #    原因:证书字符串换行没缩进,解决:证书内容和冒号同一行,不要换行
 # 2、error: context "xxx" does not exist
 #    原因:context内cluster/user名称和对应块name字符不一致,检查拼写、大小写
 # 3、connection refused / timeout
 #    原因:server地址IP不存在(实验cluster2就是这个情况),生产环境检查master节点是否开机、防火墙6443端口放行
 # 4、x509: certificate signed by unknown authority
 #    原因:ca根证书粘贴错误、混用了其他集群的CA证书,生产环境必须使用对应集群自身ca.crt
 ​
 ​
 ​
 ​
 ​

配置文件定义了以下资源:

  • clusters:集群信息,包括集群名、authority、地址和端口。

  • users:用户信息,包括用户名、certificate和key。

  • contexts:上下文信息,包括上下文名称、集群名、用户名和namespace。

多集群切换

kubernetes 自带工具

查看集群清单

 [root@master30 ~ 15:42:39]# kubectl  config  get-clusters 
 NAME
 cluster1
 cluster2
 ​

查看上下文清单

 [root@master30 ~ 15:42:50]# kubectl  config  get-contexts 
 CURRENT   NAME               CLUSTER    AUTHINFO         NAMESPACE
 *         cluster1-context   cluster1   cluster1-admin   default
           cluster2-context   cluster2   cluster2-admin   default
 ​

* 代表当前使用的上下文

切换上下文

 #执行切换集群命令,切换到cluster2集群
 [root@master30 ~]# kubectl config use-context cluster2-context
 [root@master30 ~ 15:43:03]# kubectl  config  use-context cluster2-context 
 Switched to context "cluster2-context".
 #CURRENT:标记当前默认使用的集群上下文,* 星号 = 激活状态
 [root@master30 ~ 15:43:22]# kubectl  config  get-contexts 
 CURRENT   NAME               CLUSTER    AUTHINFO         NAMESPACE
           cluster1-context   cluster1   cluster1-admin   default
 *         cluster2-context   cluster2   cluster2-admin   default
 ​

kubectx-第三方工具

kubectx 是开源第三方 K8s 辅助工具,配套还有 kubens(切换命名空间)。 原生 kubectl 切换集群上下文、查看上下文、重命名 / 删除上下文命令冗长;kubectx工具可以简化多集群环境下上下文管理操作,替代复杂 kubectl config 系列命令,提升运维效率。

kubectx 安装

 [root@master30 ~ 11:16:24]# wget https://codeload.github.com/ahmetb/kubectx/zip/refs/heads/master -O kubectx.zip
 [root@master30 ~ 11:18:03]# unzip  kubectx.zip
 [root@master30 ~ 11:18:15]# ls kubectx-master/
 cmd         CONTRIBUTING.md  go.sum  internal  kubens   README.md
 completion  go.mod           img     kubectx   LICENSE  test
 ​
 #输出结果字段解释:
 #kubectx:主执行脚本(bash),核心程序;
 #kubens:配套切换命名空间工具;
 #completion/:bash/zsh 自动补全脚本,输入命令按 Tab 自动提示上下文名称。
 #实验目的:确认解压完整,找到需要复制的脚本与补全文件。
 ​
 [root@master30 ~ 11:20:45]# cp kubectx-master/kubectx   /usr/local/bin/
 [root@master30 ~ 11:21:16]# chmod  +x /usr/local/bin/kubectx 
 ​
 # 配置补全
 [root@master30 ~ 11:22:04]# cp kubectx-master/completion/kubectx.bash /etc/bash_completion.d/
 [root@master30 ~ 11:22:53]# source /etc/bash_completion.d/kubectx.bash 

kubectx 帮助

 [root@master30 ~ 11:23:10]# kubectx -h
 Manage and switch between kubectl contexts.
 ​
 USAGE:
   kubectx                       : list the contexts
   kubectx <NAME>                : switch to context <NAME>
   kubectx -                     : switch to the previous context
   kubectx -c, --current         : show the current context name
   kubectx <NEW_NAME>=<NAME>     : rename context <NAME> to <NEW_NAME>
   kubectx <NEW_NAME>=.          : rename current-context to <NEW_NAME>
   kubectx -d <NAME> [<NAME...>] : delete context <NAME> ('.' for current-context)
                                   (this command won't delete the user/cluster entry
                                   that is used by the context)
   kubectx -u, --unset           : unset the current context
 ​
   kubectx -h,--help             : show this message
 ​
   (This executable is the legacy bash-based implementation, consider upgrading to Go-based implementation.)
 ​
 ​
 ​
 逐条功能解释和实验用途介绍:
 1.kubectx                       # 无参数
 用途:列出当前 kubeconfig 里所有集群上下文,等价原生命令 kubectl config get-contexts;
 实验场景:刚登录主机,快速查看本机配置了哪些集群。
 ​
 2.kubectx <NAME>
 用途:切换到指定上下文,等价 kubectl config use-context NAME;
 实验场景:多集群来回切换,一行短命令替代长原生命令。
 ​
 3.kubectx -
 用途:切回上一次使用的上下文;
 实验场景:测试集群和生产集群反复切换,一键来回跳转,类似 cd -。
 ​
 4.kubectx -c, --current
 用途:查看当前正在使用的上下文,等价 kubectl config current-context;
 实验场景:不确定当前操作的是哪个集群,快速确认,避免误操作生产环境。
 ​
 5.kubectx <NEW_NAME>=<NAME>
 用途:给指定旧上下文重命名;
 实验场景:原生上下文名称很长(kubernetes-admin@10.1.8.30),简化为 master30,方便记忆。
 ​
 6.kubectx <NEW_NAME>=.
 用途:重命名当前正在使用的上下文;
 实验场景:当前集群上下文名字混乱,直接就地改名。
 ​
 7.kubectx -d <NAME>
 用途:删除指定上下文;
 注意:仅删除 context 绑定关系,不会删除对应的 cluster、user 证书信息,不会丢失集群凭据;
 实验场景:集群下线,清理无用上下文。
 ​
 8.kubectx -u, --unset
 用途:清空当前默认上下文;
 实验场景:临时不绑定任何集群,执行 kubectl 命令会报错,防止误操作。
 ​
 9.kubectx -h,--help
 用途:查看工具帮助手册,忘记命令时查阅。
 ​

kubectx 命令使用

 #用途:列出当前 kubeconfig 里所有集群上下文,等价原生命令 kubectl config get-contexts;
 [root@master30 ~ 11:25:25]# kubectx 
 cluster1-context
 cluster2-context
 ​
 [root@master30 ~ 11:25:38]# kubectx -c
 cluster2-context
 ​
 #切换到 cluster1 集群
 [root@master30 ~ 11:26:14]# kubectx cluster1-context
 Switched to context "cluster1-context".
 ​
 #查看当前正在使用的上下文
 [root@master30 ~ 11:26:14]# kubectx -c
 cluster1-context
 ​
 #清空当前默认上下文;
 [root@master30 ~ 11:26:32]# kubectx -u
 Unsetting current context.
 Property "current-context" unset.
 ​
 #查看当前正在使用的上下文,等价 kubectl config current-context;
 [root@master30 ~ 11:26:36]#kubectx -c
 error: current-context is not set

实验完成后再把配置文件改回单集群配置:
 [root@master30 .kube 15:46:24]# vim config 
 [root@master30 ~ 15:47:35]# cat .kube/config 
 apiVersion: v1
 clusters:
 - cluster:
     certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJSnoxdWxiZGRjYzB3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TmpBM01EVXhNalU0TVRWYUZ3MHpOakEzTURJeE16QXpNVFZhTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUURWaUl1RHNsakFMT09zVXlyTlBWRFFQQUNDUzBKd2FqeE9URDg3VGFtQ2w5cVNPaWFaWnpDZzh2MXUKZVd1NkE3dk5HdEdBRGluL3BlNkpTcURIOGNiNUpkVytDbXdEdkFMenJkYjlmNWxUeitETzVkSUJCTE5HTDR5dAo5dENKWlk1ZXpuZkVHV0NiTXUxU3ZuOG1ReDRpNU9haWcvOUM0d1BCOHkwS0VpN1c4TmF1SXdMRkZ1bCt0Y2pVCjV1SHA0MFYyVXBodW9VeUE5RWxKTFZzLzc5eWtqRWNhY1lzQVdldGI5bExpSXJFbXB3ckt0TWpDbm45V3ppZk8KM2NreEY1OCsxWStBT2x4Y3lubGhIVFFmWE1Pbzl5czRrVHVPRW43b2czaG50TCtyUzNidlNhenFqZVpZYkZiTQpZMFBPYmYwODI3eitlMXQwK3lBRVhNL2htaXVkQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJSU1lYenhQRnkvUTZlblpTei9lenNCTXdGOEhUQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ0VkMUo2SytZYgpqVEliSlpicXV4SkJyaW81OHVoS0xOclFlQVljVkVHaEQ0Z0VLNGVFYTNyd29CbkVVcmlXMEJzejRhdlJkY3hhCmw0NDFZZEFIWCtKdjFCYnhlVXBjTE5NbzJ5UllWd2pRUTllMFZqSk5CRHlla1ZIYURkRFFSeVFUOUdYdThtcWsKWUdZSTY1QlQzTTg5SzFmZ25uWjlNVmE4UlNwelJPbTkwTmdRd3loWEo1MFA2d21FVWhicWxNRkVnTVFQeHdpcwpZZG95ZWNJaGJNWGtadU1VT20wbUo3emhtTW9vS1pscDZRelcvQ0R1MHRLUUZNZXJkRjJFaVVQSGJ0SkhSdUU4CjA3a2JIYTdpNEtHOXVxcGNUMWxnc3lhdGNnNTllTHErMlZIS1J2aFltSis0a296Skg3SU1oNEQyN2Q5N3p3MU4KUXluelhCTDRkbnVICi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
     server: https://10.1.8.30:6443
   name: kubernetes
 contexts:
 - context:
     cluster: kubernetes
     namespace: kube-system
     user: kubernetes-admin
   name: kubernetes-admin@kubernetes
 current-context: kubernetes-admin@kubernetes
 kind: Config
 preferences: {}
 users:
 - name: kubernetes-admin
   user:
     client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURLVENDQWhHZ0F3SUJBZ0lJRytTYysva1YvT0l3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TmpBM01EVXhNalU0TVRWYUZ3MHlOekEzTURVeE16QXpNVFphTUR3eApIekFkQmdOVkJBb1RGbXQxWW1WaFpHMDZZMngxYzNSbGNpMWhaRzFwYm5NeEdUQVhCZ05WQkFNVEVHdDFZbVZ5CmJtVjBaWE10WVdSdGFXNHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFESC9hMTAKMnkvSGI3dHBNVzYxY1J2VHBjbThnSmNOVmhpM1EyUm40ZSsvVXdRa1MvaldxYkR4SjFra3ZkOVhMbUY2a0RtMQptNGVFUFlGWGpKTXExSENoY1VER0RUQ3VmU005YkxZbW1EU3NNWVppQklENVJ5ZDlQNU8yZ0g5MEx2RkZpSWxPCmFGcnBjcGlqU21GNGxjb3VDdkhyZFlUcVFjbHUwVm9BU3BXNWRKRVNEN1FZNFlnekpRclBTLzFTOTg0RzROVzAKeExIVWptMy90V1R2NnI0YkIzL1o0ekRYZUZ5bmMrbDV4dzEvZThoRm1lSTdxek13aitLYlJHV1Yremt1VkFxUApiZExXUVhJSEZYZmR0cEQ0Y0puem1vU0l1cnQ3dEcrbldqNXJhakl2UGRUVEMvNlRQL2k0Z1czb1FQVjdLNWFBCkZ4MmJMcm9hdENaaHJPZDVBZ01CQUFHalZqQlVNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUsKQmdnckJnRUZCUWNEQWpBTUJnTlZIUk1CQWY4RUFqQUFNQjhHQTFVZEl3UVlNQmFBRkZKaGZQRThYTDlEcDZkbApMUDk3T3dFekFYd2RNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUI5RUhsVUwxL3hPTHFtdWxhdkhaSzJ4ZXBlCmp4elJUNW9PbHVyM2hLMFBhWDRZMkprRGZ4V1lNU0tRQlJMSjVZQ3BUa1NjcWNLMFpGNWM5M3NsYXNNdkFkMXIKVFFsVmIyMTUzYXAwb3VBbWJtdkxHanc0R2lOb1BwaVd1L2k5aHpuTDdDUWZiQWxNdGJ4TjNUZzdGa1pCRGRlNwpPZ3M5UXJmTXQ2dVFoMUFMM3d1dTNqOC9wUFZkaGVJOUhmZlNXaTBYM1puYTNUVzBQUU9NOFl6cC9xQTJuQkNhCmpvZFQ5V1BtSHkrVDhEM0l4MFcwYmhvY29nWFZvVGF6U1MyYmRJVXZVYWJMUXh2NTc0ZzVKUjR1RmVwN3ZRczEKQkVEZmN5VzNXck1yUzJyT2ZEQkxzVXBKMUl6VXJQYXFFTFdvd29tUnZHb0RoQ0grQkc0dDhrQ2g5WVlMCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
     client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBeC8ydGROc3Z4Mis3YVRGdXRYRWIwNlhKdklDWERWWVl0ME5rWitIdnYxTUVKRXY0CjFxbXc4U2RaSkwzZlZ5NWhlcEE1dFp1SGhEMkJWNHlUS3RSd29YRkF4ZzB3cm4walBXeTJKcGcwckRHR1lnU0EKK1VjbmZUK1R0b0IvZEM3eFJZaUpUbWhhNlhLWW8wcGhlSlhLTGdyeDYzV0U2a0hKYnRGYUFFcVZ1WFNSRWcrMApHT0dJTXlVS3owdjlVdmZPQnVEVnRNU3gxSTV0LzdWazcrcStHd2QvMmVNdzEzaGNwM1BwZWNjTmYzdklSWm5pCk82c3pNSS9pbTBSbGxmczVMbFFLajIzUzFrRnlCeFYzM2JhUStIQ1o4NXFFaUxxN2U3UnZwMW8rYTJveUx6M1UKMHd2K2t6LzR1SUZ0NkVEMWV5dVdnQmNkbXk2NkdyUW1ZYXpuZVFJREFRQUJBb0lCQUQ3anppVWVQRU1xSnJRbwp3Rmk4YmZTN2dOb1BVZkQycnlVS1EwdkxwL254WUM4TjJQMmdOUzFRbzE3RGVyVk90NGEwVGdHSEhER0FxZWpmCkl2Um9BOWN3NXg2Z3pUdEJ6TkFuSEl5OGRtdmowdytGdlEwbXpBczk3L1NIS2cxZUthOGxCWkNyamxNMUh6elMKU2g2Q2RDYlFlRTBFRXIwYjNQMUZSbGtyR3pSTEhtSTYxSG45Z1NYMDUzUVdLdklhRFZXbWczeW5LZzRsVjlKSwpSaThUdFdEOUl4dkRVSkRMUW11ckVzYTVncW5JK3NKaUJSRUV5em1XQzVQVlJidm5zR3RGYUpxVDFSR1dPQ2RzCk5LTzZkV3ptamtlcjZuZFRvZmxnWmdBUEpOYnViOG9sd04vUjNsVmRxWkFLdmVEUnlSbms3K1dwZnBJZWhtUnMKNk14TDE1RUNnWUVBMm55amlDTGcydHAvR1lQZXBXMFI1eTFtaGFBZ0Q1bkFPRjJSRWRxTmdYWThtSWtTOHIwNApMU3NGYy9WcFQyN0tTSndzSG9aSjlFall0V0UwU0l3anBZVDN3V0JpN25DWHBYSlFpRHVoSS9CbC9LWDhPUGRFClo1U05pMEZzY0VBT2lLUm1MS1pEeXFCRHJhaEFCY1BqV2thWEtkRXFjOHR4czgwVWhkdEdlSVVDZ1lFQTZsUVIKcTZKT0dhaUUrNGZBZTFWK3dpdjQrY3dLMFpjTFprVGovSU1KaUk2TkhkWUU1UE5DMFBVWEhid3BRWFY1dXd1MgpZNUJLVExuUVZDVkxybDd0Qm5Cb3JBTHRicUkzUElyNStlZ2c5cndMbms1NUZ4N2JuR3ZKYlJzNUFnZCtOZTBCCk8zY0s0WXBSNFVpU2JDamtMMEI2dHM4VVhFRThHdkxrS3VOdVgyVUNnWUFvUEUzTlUwYi9acitEVG1LaEtrM2kKdWR5b2ZRMktjZkVSTUVIMy9MeVVlOWE2N0h0ZDBuVFc5SlpEZlkxUVFJSG1EMFNjdG5SR0ZXZzdOdFJ2QzhmQQp3cFR4dXJOZFg4UzloaWpJZmRxMkNKNXZnWTNLVzlid0VFNWt0NzZsaVZaajJZcXJiRThOc0tmbUFoY1FPTHZVCnN5MUJXVEN0TkdrVENKQmYranFuRlFLQmdGeEczdTZINjltTzAwOTZGZ0o3bUg4K2NiMXM3Slc4dFhDQWtJZFAKMHVGRHdhNk9LVDgveklBZEJBMWhtNTE3ZFlTRENFQU5BalZVdHdWcjZuR3dVQWJKSFc4ZmVBQ3BRTGRHdzBuMgpiNFM2YUpqZXJqQzhwaDdqRTE4ejZTOHpaREE0Tk5RRi9QTDBWV294K2ZjOTR4MzRkbHFuRVkyQzR2aDV6Z0JWCnI1RkJBb0dBSHhmaWRqN2IzR2NvcTNMcENnaTcySStxdkhrOTI2YjNzTzlzbFFFcEpGalNuQzZOb04rdmFHekIKWG5ZVzJ3L0VQNVUyenR1WDVVWkdvSC9uSEVvU2FYTTFjQTFLVUNJRm5hcFF3eUtrRGxMMlltMllpbDEzWW9xbgp1NEtibjVlazhQRHZ0NXBQR3ZTKzYvRUt3eXVQRzBTbG9BU1V1QVhMNEdEaFdwVHFVZU09Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
 ​
 #发现kubectl命令可以正常使用
 [root@master30 ~ 15:47:21]# kubectl  get nodes 
 NAME                STATUS   ROLES           AGE   VERSION
 master30.zy.cloud   Ready    control-plane   18h   v1.30.2
 worker31.zy.cloud   Ready    <none>          18h   v1.30.2
 worker32.zy.cloud   Ready    <none>          18h   v1.30.2
 ​
 #查看已配置的集群上下文列表(也就是看有几套集群,和每套集群的详细信息,*表示当前正在使用操作的集群)
 [root@master30 ~ 15:49:09]# kubectl  config get-contexts 
 CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
 *         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   kube-system
 #查看集群列表:(简洁查看集群配置信息)
 [root@master30 ~ 15:50:01]# kubectl  config  get-clusters 
 NAME
 kubernetes
 ​

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐