Kubernetes: Kubernetes 工具
- TAGS: Kubernetes
MetaLB
轻量级负载均衡(类型为 LoadBalancer 的服务)
# 查看集群版本 1.37 root@master01:~# kubectl get node NAME STATUS ROLES AGE VERSION node01.jasper.org Ready worker 45h v1.37.0 # 检查集群的代理模式。 nftables root@master01:~# curl 127.0.0.1:10249/proxyMode nftables
安装
# 2026.8 不再支持 ipvs ,所以不需要特殊处理 curl -L -o metallb-native.yaml \ https://raw.githubusercontent.com/metallb/metallb/v0.16.1/config/manifests/metallb-native.yaml ## 或挂镜像下载 curl -L -o metallb-native.yaml \ https://ghfast.top/https://raw.githubusercontent.com/metallb/metallb/v0.16.1/config/manifests/metallb-native.yaml # 查看镜像版本 grep -E '^\s+image:' metallb-native.yaml # 应用 kubectl apply -f metallb-native.yaml # speaker 是 DaemonSet + hostNetwork: true kubectl -n metallb-system get pod -o wid
# 网络信息 ## node root@master01:~# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME master01.jasper.org Ready control-plane 21h v1.37.0 10.103.236.201 <none> Ubuntu 26.04.1 LTS 7.0.0-31-generic (arm64) containerd://2.3.5 master02.jasper.org Ready control-plane 20h v1.37.0 10.103.236.202 <none> Ubuntu 26.04.1 LTS 7.0.0-31-generic (arm64) containerd://2.3.5 master03.jasper.org Ready control-plane 20h v1.37.0 10.103.236.203 <none> Ubuntu 26.04.1 LTS 7.0.0-31-generic (arm64) containerd://2.3.5 node01.jasper.org Ready worker 46h v1.37.0 10.103.236.204 <none> Ubuntu 26.04.1 LTS 7.0.0-31-generic (arm64) containerd://2.3.5 node02.jasper.org Ready worker 46h v1.37.0 10.103.236.205 <none> Ubuntu 26.04.1 LTS 7.0.0-31-generic (arm64) containerd://2.3.5 node03.jasper.org Ready worker 22h v1.37.0 10.103.236.206 <none> Ubuntu 26.04.1 LTS 7.0.0-31-generic (arm64) containerd://2.3.5 ## service cidr root@master01:~# grep -oE '\-\-service-cluster-ip-range=[^ ]*' /lib/systemd/system/kube-apiserver.service --service-cluster-ip-range=192.168.0.0/16 ## pod cidr root@master01:~# kubectl get ippool -o custom-columns=NAME:.metadata.name,CIDR:.spec.cidr NAME CIDR default-ipv4-ippool 172.16.0.0/12 root@master01:~# kubectl get ippools.crd.projectcalico.org -o yaml | grep cidr cidr: 172.16.0.0/12
配置
# manifest 不含任何配置,装完两个组件会空转。先确认节点网段: kubectl get nodes -o wide ip -4 addr show | grep 10.103.236 # 掩码确认 # 找空闲地址 interface=enp2s0 for i in $(seq 240 250); do arping -c 2 -w 1 -I $interface 10.103.236.$i >/dev/null 2>&1 \ && echo "10.103.236.$i 已被占用" done # 定义分配给负载均衡器服务的 IP # 挑一段同网段、不在 DHCP 池里的空闲 IP # 如节点在 10.103.236.0/24 段,就从这里划出闲置 ip cat >ippool.yaml << EOF apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: default-pool namespace: metallb-system spec: addresses: - 10.103.236.240-10.103.236.250 --- #二层转发功能 apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: default-l2 namespace: metallb-system spec: ipAddressPools: - default-pool EOF kubectl apply -f ippool.yaml # 查看 root@master01:~# kubectl -n metallb-system get ipaddresspool NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES default-pool true false ["10.103.236.240-10.103.236.250"] root@master01:~# kubectl -n metallb-system get ippools NAME AGE default-ipv4-ippool 41h root@master01:~# kubectl -n metallb-system get l2advertisements NAME IPADDRESSPOOLS IPADDRESSPOOL SELECTORS INTERFACES default-l2 ["default-pool"]
使用
cat > n.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
EOF
kubectl apply -f n.yaml
root@master01:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 192.168.0.1 <none> 443/TCP 2d2h
nginx LoadBalancer 192.168.21.226 10.103.236.240 80:30963/TCP 4s
虚拟节点
Kurl
kURL 是一个定制的 Kubernetes 发行版创建工具。自定义选择安装哪些组件。
#选择好,安装 curl https://kurl.sh/latest | sudo bash
镜像
- configmap-reload 监听目录变化
docker pull ghcr.io/jimmidyson/configmap-reload:dev
集群管理
快速部署
部署工具
- kubeadm 原生
- kubekey
- sealos
- kubeaz
- minikube
- kind
- kubespray
- K0S
- 近原生 k8s
- Rancher
- k3s
- RKE2
kubekey
集群创建工具
# linux KUBEKEY_VERSION=4.0.6 ARCH=$([ `arch` = "aarch64" ] && echo arm64 || echo amd64) wget https://github.com/kubesphere/kubekey/releases/download/v${KUBEKEY_VERSION}/kubekey-v${KUBEKEY_VERSION}-linux-${ARCH}.tar.gz tar xf kubekey-v${KUBEKEY_VERSION}-linux-${ARCH}.tar.gz kk
# 1. 生成 inventory.yaml ./kk create inventory -o . cat > inventory.yaml <<EOF apiVersion: kubekey.kubesphere.io/v1 kind: Inventory metadata: name: default spec: hosts: localhost: connector: password: 123456 # 本地连接时这是 sudo 密码 groups: k8s_cluster: groups: - kube_control_plane - kube_worker kube_control_plane: hosts: - localhost kube_worker: hosts: - localhost etcd: hosts: - localhost EOF # 如果你是 root 直接跑,connector 那段可以整个删掉——type 会根据节点名自动识别成 local。 # 2. 创建集群配置文件 ./kk create config --with-kubernetes v1.37.0 -o . # 按需修改 ## kubernetes.kube_proxy.mode 只能选 ipvs 或 iptables,没有 nftables。 ## KubeKey 默认 Pod 10.233.64.0/18、Service 10.233.0.0/18 vim config-v1.37.0.yaml zone: "cn" # 关键,不然镜像还是走境外源 kubernetes: cluster_name: my-cluster control_plane_endpoint: host: lb.kubesphere.local type: local # 单节点保持 local,会往 /etc/hosts 写 127.0.0.1 cni: type: calico pod_cidr: 10.233.64.0/18 # 默认值 service_cidr: 10.233.0.0/18 # 默认值 cri: # containerd 或 docker,默认 containerd # 3 安装 ./kk create cluster -i inventory.yaml -c config-v1.34.0.yaml # 验证 kubectl get nodes # 4. 删除集群 ./kk delete cluster --all --with-data
k9s
命令行终端集群管理工具
# linux K9S_VERSION=0.51.0 ARCH=$([ `arch` = "aarch64" ] && echo arm64 || echo amd64) wget https://github.com/derailed/k9s/releases/download/v${K9S_VERSION}/k9s_Linux_${ARCH}.tar.gz tar xf k9s_Linux_${ARCH}.tar.gz -C /usr/local/bin k9s
使用
k9s 的完整键位可以在程序内按 ? 查看帮助,按 ctrl-a 查看所有资源别名。
- vim 类 jk 上下选择,
:选择 crd 的类型,q退出。 - 键位以 k9s 官方 README Key Bindings 为准。
启动
k9s # 默认启动 k9s -n kube-system # 指定命名空间 k9s --context jasper-org # 指定集群 context k9s --readonly # 只读模式,禁用 delete/kill/edit k9s info # 打印配置、日志、插件、别名文件的实际路径 k9s help # 所有 CLI 选项
导航
| 操作 | 键 |
|---|---|
| 打开资源视图 | :pod⏎ (单数/复数/简称/别名都认) |
| 指定命名空间 | :pod kube-system⏎ |
| 直接带过滤 | :pod /nginx⏎ |
| 直接带标签 | :pod app=headlamp,env=prod⏎ |
| 切换集群 context | :ctx⏎ 或 :ctx 集群名⏎ |
| 切换命名空间 | :ns⏎ ,在列表里按 u 使用 |
| 返回上一层 | esc |
| 回到上一个命令(类似 cd -) | - |
| 命令历史前后翻 | [ / ] |
| 所有资源别名速查 | ctrl-a |
| 显示帮助 | ? |
| 退出 | :q⏎ 或 ctrl-c |
过滤和排序-这是找问题的核心区。
| 操作 | 键 |
|---|---|
| 正则过滤 | /nginx⏎ ,支持 fred\vert{}blee |
| 反向过滤 | /! nginx⏎ 留下*不*匹配的 |
| 按标签过滤 | /-l app=nginx⏎ |
| 模糊查找 | /-f nginx⏎ |
| 只看故障/错误 | ctrl-z |
| 按状态排序 | shift-s |
| 按时间排序 | shift-a |
| 按名称排序 | shift-n |
| 按命名空间排序 | shift-p (仅全命名空间视图下可用) |
| 按当前列排序 | shift-o |
| 宽列(IP、节点等) | ctrl-w |
| 列左移 / 右移 | shift-← / shift-→ |
ctrl-z是运维最该记住的一个键。集群几百个 Pod,一键只留异常的, 比kubectl get pod -A | grep -v Running好用得多。
排查单个资源
| 操作 | 键 |
|---|---|
| describe | d |
| 查看 YAML | y |
| 查看日志 | l |
| 上一次容器的日志 | p |
| 进容器 shell | s |
| attach | a |
| 编辑 | e |
| 跳到 owner | shift-j |
| 刷新视图 | ctrl-r |
| 复制资源名 | c |
| 复制命名空间 | n |
p看崩溃前的日志,等价于kubectl logs --previous。 CrashLoopBackOff 全靠它。shift-j从 Pod 一路跳到 ReplicaSet 再到 Deployment, 省掉翻 ownerReferences 的功夫。
日志视图内的键
| 操作 | 键 |
|---|---|
| 切换自动换行 | w |
| 切换时间戳 | t |
| 全屏 | f |
f 全屏同样适用于 YAML 和 Details 视图
找依赖关系
| 操作 | 键 | 适用对象 |
|---|---|---|
| UsedBy — 谁在用这个 | u |
ServiceAccount / PVC / Secret / ConfigMap |
| 查看 ReplicaSets | z |
Deployment 视图 |
| Warp to namespace | w |
有命名空间列时 |
u这个很多人不知道。"这个 Secret 能不能删"、"这个 PVC 挂在哪", 选中按u直接列出引用方。
日常操作
| 操作 | 键 | 适用对象 |
|---|---|---|
| 滚动重启 | r |
Deployment / DaemonSet / StatefulSet |
| 回滚 | ctrl-l |
ReplicaSet 视图 |
| 手动触发 | t |
CronJob |
| cordon / uncordon | u |
Node 视图 |
| drain | r |
Node 视图 |
| 端口转发 | shift-f |
Pod / Service / Container |
| 查看已有转发 | f |
同上 |
| 压测(启动/停止) | b |
Service / Port-forward |
*警告*:=r= 在不同视图含义不同。工作负载视图是滚动重启, *Node 视图是 drain*。手滑代价差很远。
生产环境建议-默认开只读
k9s --readonly
或写进配置文件:
k9s: readOnly: true
多集群切换
# 1.在对方集群上执行,建一个专用 ServiceAccount kubectl create sa k9s-ops -n kube-system kubectl create clusterrolebinding k9s-ops \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:k9s-ops ## k8s 1.24 之后 SA 不再自动生成永久 Secret, ## kubectl create token 签出来的有期限,会过期。长期用要手动建: kubectl apply -f - <<'EOF' apiVersion: v1 kind: Secret metadata: name: k9s-ops-token namespace: kube-system annotations: kubernetes.io/service-account.name: k9s-ops type: kubernetes.io/service-account-token EOF ## 然后组装 kubeconfig SERVER=https://10.103.236.236:6443 CTX=prod-cluster CA=$(kubectl -n kube-system get secret k9s-ops-token -o jsonpath='{.data.ca\.crt}') TOKEN=$(kubectl -n kube-system get secret k9s-ops-token -o jsonpath='{.data.token}' | base64 -d) cat > ./$CTX.kubeconfig <<EOF apiVersion: v1 kind: Config clusters: - name: $CTX cluster: server: $SERVER certificate-authority-data: $CA users: - name: $CTX user: token: $TOKEN contexts: - name: $CTX context: cluster: $CTX user: $CTX current-context: $CTX EOF # 2. 本地合并 kubeconfig ## 在合并前,先给对方的文件改名,避免冲突 ## 确认 context 是不是叫 kubernetes-admin@kubernete KUBECONFIG=./prod-cluster.kubeconfig kubectl config view --minify --raw KUBECONFIG=./prod-cluster.kubeconfig kubectl config rename-context \ kubernetes-admin@kubernetes prod-cluster ## 合并 cp ~/.kube/config ~/.kube/config.bak KUBECONFIG=~/.kube/config:./prod-cluster.kubeconfig \ kubectl config view --flatten > /tmp/merged mv /tmp/merged ~/.kube/config chmod 600 ~/.kube/config # --flatten 是关键——它把证书文件的内容内嵌进去。 # 不加的话合并结果里只是 certificate-authority: /path/to/ca.crt # 这种路径引用,换台机器就失效了。 # 验证 kubectl config get-contexts
k9s 里切换
- 列出并切换 :ctx⏎
- 直接切到指定集群:ctx prod-cluster⏎
- 启动时指定:k9s –context prod-cluster
- 用别的 kubeconfig 文件:k9s –kubeconfig /path/to/config
- 跨集群看资源 :pod @prod-cluster⏎
k9s 每集群独立配置
$XDG_DATA_HOME/k9s/clusters/<集群名>/<context名>/config.yaml k9s: cluster: prod-cluster readOnly: true # 这个集群强制只读 namespace: active: default lockFavorites: false favorites: - kube-system - headlamp - metallb-system view: active: po # 进来默认落在 Pod 视图 featureGates: nodeShell: true # 允许在 Node 视图按 s 进宿主机