单机内 K8S 集群环境切换指南

在实际开发运维中,很少有人只用一个 K8S 集群。本地有 Minikube 或 Kind 的测试集群,公司有开发、预发、生产等多套环境,还可能涉及公有云托管的 K8S(如 TKE、ACK、EKS)。如何在一台机器上优雅地管理多个集群环境,并在它们之间快速切换?

本文从 kubeconfig 的底层结构出发,覆盖多集群配置、Context 切换、文件合并、安全认证等全流程,让你在单机环境中像「切换频道」一样切换 K8S 集群。

K8S 环境切换全景

在一台本地开发机上,你可以通过一个 kubeconfig 文件管理多个 K8S 集群:

本地开发机 (kubeconfig)

├── kubectl --context=minikube ──► Minikube / Kind 本地测试集群
├── kubectl --context=dev ──► 开发环境 (dev.example.com:6443)
├── kubectl --context=staging ──► 预发环境 (staging.example.com:6443)
└── kubectl --context=prod ──► 生产环境 (prod.example.com:6443)

每个 context 就是一个「标签」,绑定了集群地址 + 用户凭证 + 默认命名空间。切换 context 等于切换目标集群。

kubeconfig 与 Context 基础

kubectl 查找集群连接信息的默认位置是 ~/.kube/config,这个 YAML 文件由三层核心概念组成:

概念 作用 类比
Cluster 定义集群 APIServer 地址及 TLS 证书 一套房子的地址和门禁
User 定义客户端身份凭证(证书 / Token / BASIC) 你手里的钥匙
Context cluster + user + namespace 三元组绑定并命名 哪套钥匙开哪扇门,进哪个房间
# ~/.kube/config 结构示意
apiVersion: v1
kind: Config
clusters:
- name: minikube
cluster:
server: https://127.0.0.1:6443
certificate-authority-data: <base64 CA> # 或 certificate-authority: /path/ca.crt

users:
- name: minikube-user
user:
client-certificate-data: <base64 cert>
client-key-data: <base64 key>

contexts:
- name: minikube
context:
cluster: minikube
user: minikube-user
namespace: default

current-context: minikube

一句话总结: Context 就是「用谁的钥匙,连接哪个集群,默认进哪个命名空间」的三合一标签。

查看当前环境

随时确认你现在连的是哪个集群:

# 查看当前使用的 Context(最常用)
kubectl config current-context
# 输出:minikube

# 查看完整配置
kubectl config view

# 只查看 Context 列表
kubectl config get-contexts
# 输出示例:
# CURRENT NAME CLUSTER AUTHINFO NAMESPACE
# * minikube minikube minikube default
# dev dev dev-user dev
# staging staging staging-user pre
# prod prod prod-user prod

# 查看当前 Context 的详情(含集群地址)
kubectl cluster-info

CURRENT 列有 * 号的就是当前正在使用的 Context。

添加与配置外部集群

方式一:直接修改 kubeconfig(certificate-auth 场景)

假设你拿到一个外部 K8S 集群的证书和地址:

# 1. 设置集群地址和 CA 证书
kubectl config set-cluster prod-cluster \
--server=https://prod-api.example.com:6443 \
--certificate-authority=./ca.pem \
--embed-certs=true

# 2. 设置客户端凭证
kubectl config set-credentials prod-admin \
--client-certificate=./admin.pem \
--client-key=./admin-key.pem \
--embed-certs=true

# 3. 创建 Context(将 cluster + user 绑定)
kubectl config set-context prod \
--cluster=prod-cluster \
--user=prod-admin \
--namespace=production

# 4. 切换到新 Context
kubectl config use-context prod

--embed-certs=true 会将证书内容编码为 Base64 嵌入到 kubeconfig 中,方便单文件迁移。如果不需要嵌入,可以省略此参数,使用文件路径引用。

方式二:Token / Password 认证

# 使用 Token(常用于 Dashboard ServiceAccount)
kubectl config set-credentials ci-bot --token=eyJhbGciOiJSUzI1Ni...

# 使用 BASIC Auth
kubectl config set-credentials admin-user --username=admin --password=xxx

方式三:使用集群管理员提供的 kubeconfig

更多情况下,运维会直接发给你一个配置文件:

# 直接覆盖或备份后替换
cp ~/.kube/config ~/.kube/config.bak
cp ./new-cluster-config.yaml ~/.kube/config

但更推荐的方式是合并到现有配置中(见下文)。

切换 K8S 环境

基础切换命令

# 切换到某个 Context(此后所有 kubectl 命令针对该集群)
kubectl config use-context dev

# 验证是否切换成功
kubectl config current-context
# 输出:dev

临时切换(单条命令级别)

有时不想改变「默认 Context」,只需临时跑一条命令:

# 只对当前命令使用指定 Context
kubectl get pods --context=prod

# 同时对比多个环境
kubectl get nodes --context=staging
kubectl get nodes --context=prod

这种方法在巡检或对比环境差异时非常实用。

修改默认 Namespace

# 在已有 Context 上修改默认 namespace
kubectl config set-context dev --namespace=my-app

# 验证
kubectl config view --minify -o jsonpath='{.contexts[?(@.name=="dev")].context.namespace}'

多 kubeconfig 合并策略

当你有多个独立 kubeconfig 文件时,不要来回覆盖,而是将它们合并。

策略一:手动合并(最常用)

# 合并两个配置文件
KUBECONFIG=~/.kube/config:./new-cluster-config.yaml \
kubectl config view --flatten > ~/.kube/config.new

# 备份后替换
mv ~/.kube/config ~/.kube/config.bak
mv ~/.kube/config.new ~/.kube/config

--flatten 会将所有证书引用转为内嵌 Base64,生成一个自包含的配置文件。

策略二:使用 KUBECONFIG 环境变量(推荐)

不合并文件,而是让 kubectl 自动合并多个配置:

# 同时加载多个配置
export KUBECONFIG=~/.kube/config:~/project-a/kubeconfig:~/project-b/kubeconfig

kubectl 启动时会读取 KUBECONFIG 环境变量中列出的所有文件并合并,如有同名 Conflict 则以第一个为准。

可以写进 ~/.bashrc~/.zshrc 持久化:

# ~/.zshrc
export KUBECONFIG="$HOME/.kube/config:$HOME/.kube/dev-config:$HOME/.kube/prod-config"

kubectl 查找 kubeconfig 的完整流程:

kubectl 启动

├── KUBECONFIG 环境变量存在?──是──► 读取 KUBECONFIG 中各文件
│ │
└── 否 │
│ │
▼ ▼
读取 ~/.kube/config 合并所有 cluster/user/context


按 current-context 决定目标集群


执行 API 请求

策略三:按目录分拆管理

对于多项目团队,可以在 ~/.kube/ 下创建独立的配置文件,如:

~/.kube/
├── config # 主配置(比如 minikube)
├── dev-config # 开发环境
├── staging-config # 预发环境
├── prod-config # 生产环境
└── test-config # 自动化测试环境

然后通过在 shell profile 中设置 KUBECONFIG 捕获所有文件:

# 自动加载 ~/.kube/ 下所有 config* 文件
export KUBECONFIG=$(find ~/.kube -name "config*" | tr '\n' ':')

实用工具

kubectx / kubens 快速切换

kubectx 是目前最流行的 Context 切换工具,提供交互式选择和模糊搜索:

# 安装(macOS/Linux)
brew install kubectx

# 查看 Context 列表(交互式,高亮当前)
kubectx

# 切换
kubectx prod

# 回到上一个 Context(类似 cd -)
kubectx -

# 切换 Namespace
kubens kube-system

kubectl alias 简化

# 常用别名
alias k='kubectl'
alias kx='kubectl config use-context'
alias kgc='kubectl config get-contexts'
alias kcc='kubectl config current-context'
alias kcg='kubectl config view --minify -o jsonpath="{.clusters[0].cluster.server}"'

# 使用示例
kx prod
k get pods

使用 fzf 打造模糊搜索切换

如果不想安装额外工具,结合 fzf 也能实现快速搜索切换:

# 交互式切换 Context
function kx() {
local ctx=$(kubectl config get-contexts -o name | fzf --prompt="Select Context: ")
if [ -n "$ctx" ]; then
kubectl config use-context "$ctx"
fi
}

通过 kubeconfig 合并实现「一键上集群」

开发者 ──► 设置 KUBECONFIG 环境变量


加载 ~/.kube/config* 多个文件


kubectl config get-contexts


合并多个 kubeconfig 文件


返回所有集群上下文

开发者 ──► kubectl config use-context prod


切换当前 context


kubectl get nodes


通过 prod 集群地址发送 API 请求


返回节点列表 -> 展示节点信息

安全注意事项

1. 证书与 Token 的管理

# ⚠️ 永远不要将 kubeconfig 提交到 Git!
# 将 kubeconfig 加入 .gitignore
echo "kubeconfig*" >> .gitignore

# 使用 .env 文件管理敏感信息
# KUBECONFIG 路径可以存储在 .env 中,由 direnv 自动加载

2. 使用 certificate-authority(文件引用)替代内嵌

对于生产集群,建议引用文件而非内嵌证书:

# ❌ 不推荐:证书数据直接嵌在 YAML 中
clusters:
- name: prod
cluster:
certificate-authority-data: LS0tLS1CRUdJTi... # 几十行 Base64

# ✅ 推荐:引用文件路径
clusters:
- name: prod
cluster:
certificate-authority: /etc/kubernetes/pki/ca.crt

文件引用更容易审计证书更新,也方便 CI/CD 工具链注入。

3. 不同环境的 Context 命名规范

# ❌ 混乱的命名
kubectx cluster-1
kubectx main
kubectx test-cluster

# ✅ 规范的命名:<环境>-<区域/集群标识>
kubectx prod-shanghai
kubectx staging-beijing
kubectx dev # 本地开发可以简短

规范的上下文命名在多人协作和 CI 脚本中能减少大量误操作。

4. 误操作防护:Context 确认

对于高危操作,可以通过脚本强制确认当前 Context:

# confirm-context.sh
#!/bin/bash
TARGET_CTX=$1
CURRENT=$(kubectl config current-context)

if [ "$CURRENT" != "$TARGET_CTX" ]; then
echo "❌ 当前 Context 是 [$CURRENT],目标上下文是 [$TARGET_CTX],拒绝执行!"
exit 1
fi

echo "✅ Context 确认:$CURRENT,继续执行..."
# 使用方式
./confirm-context.sh dev && kubectl delete pod xxx
# 如果当前不是 dev 上下文,命令不会执行,避免误删生产 Pod

完整工作流示例

以下是一个开发者的日常:

启动 Minikube ──► 默认进入 minikube Context


开发本地应用 (kubectl apply -f dev.yaml)

├── 需要查看预发环境?──是──► 切换 Context (kubectx staging)
│ │
└── 否 ▼
│ 查看预发 Pod 状态
▼ │
继续开发 ▼
取日志排查问题

需要部署到生产?──是──► 切回本地测试
│ │
└── 否 ▼
│ 测试通过后
▼ CI/CD 发布到生产
继续开发 │

监控生产状态

常见问题排查

Q: kubectl 报错 The connection to the server <host> was refused

# 检查当前 Context
kubectl config current-context

# 检查集群地址是否正确
kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'

# 检查网络可达性
curl -k https://<api-server-address>:6443/healthz

# 如果是 Minikube,检查集群状态
minikube status

Q: 切换 Context 后报证书错误

# 证书过期或者集群 Root CA 更新了
# 重新从集群管理员获取最新的 CA 证书

# 对于测试环境,可以临时跳过证书验证(不推荐生产使用)
kubectl config set-cluster test-cluster --insecure-skip-tls-verify=true

Q: 多个 kubeconfig 合并后 Context 名冲突

# KUBECONFIG 合并时同名 Context 以第一个文件为准
# 可以通过指定唯一名称来避免冲突
# 在 set-context 时使用不同的名称
kubectl config set-context dev-company-a --cluster=dev --user=dev-user
kubectl config set-context dev-company-b --cluster=dev --user=dev-user

总结

场景 推荐做法
只有一个集群 使用默认 ~/.kube/config
本地 Minikube + 1 个远程集群 合并 kubeconfig,用 kubectx 切换
多个项目/多个远程集群 KUBECONFIG 环境变量 + 分文件管理
CI/CD 环境 使用 --context 临时参数,避免污染配置
团队协作 统一 Context 命名规范,配置确认脚本防误操作

核心原则: 不覆盖,只合并;不裸奔,加防护。掌握了 kubeconfig 的管理技巧,你就能在一台笔记本上从容驾驭从本地开发到生产环境的全部 K8S 集群。