Kubernetes 部署与集群管理------超详细笔记
本文档涵盖从 Ubuntu 系统初始化、容器运行时配置,到 kubeadm 部署 K8s 集群、网络插件、节点管理、多集群切换,以及常用运维技巧和故障排查。所有命令均附详细注释。
1. 基础环境准备(Ubuntu 24.04)
1.1 系统安装与分区
- 最小化安装,不要分配 swap 分区(K8s 强制要求)。
- 推荐分区:
/boot2G,/剩余全部(90G 以上)。 - 安装时断开网络,避免自动更新干扰,装完再配网络。
1.2 网络配置(Netplan)
Ubuntu 使用 netplan 管理网络,配置文件在 /etc/netplan/ 下(通常为 *.yaml)。
yaml
# 示例:/etc/netplan/00-static.yaml
network:
version: 2
ethernets:
ens32: # 网卡名,通过 ip a 查看
dhcp4: no
addresses:
- 10.1.8.30/24 # 静态 IP
routes:
- to: default
via: 10.1.8.2 # 网关
nameservers:
addresses: [223.5.5.5, 114.114.114.114]
- 应用:
netplan apply - 测试:
ping 10.1.8.2、ping baidu.com
1.3 软件源配置
- 系统源:华为云(
http://mirrors.huaweicloud.com/ubuntu)速度快。 - Docker 源:用于安装 containerd。
- K8s 源:阿里云(
https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/)
添加 K8s 源的完整命令:
bash
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/ /" > /etc/apt/sources.list.d/kubernetes.list
1.4 基础软件包
bash
apt update
apt install -y vim lrzsz bash-completion open-vm-tools apt-transport-https sshpass chrony
lrzsz:支持rz/sz上传下载。bash-completion:命令补全。open-vm-tools:VMware 增强工具。apt-transport-https:支持 HTTPS 源。sshpass:非交互式 SSH 登录(脚本用)。chrony:时间同步(重要,K8s 要求时间一致)。
1.5 关闭 swap 及内核参数
bash
swapoff -a && sed -i '/swap/d' /etc/fstab # 永久禁用
rm -f /swap.img # 删除可能的 swap 文件
内核参数 (/etc/sysctl.d/k8s.conf):
conf
net.bridge.bridge-nf-call-iptables = 1 # 让 iptables 处理桥接流量(K8s 必需)
net.bridge.bridge-nf-call-ip6tables = 1 # IPv6 同理
net.ipv4.ip_forward = 1 # 开启路由转发(Pod 跨节点通信需要)
vm.swappiness = 0 # 禁止使用 swap(提高性能)
- 生效:
sysctl -p /etc/sysctl.d/k8s.conf
加载内核模块 (/etc/modules-load.d/k8s-net.conf):
conf
overlay
br_netfilter
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
- 立即加载:
modprobe overlay br_netfilter ip_vs ...
1.6 主机名与 hosts 解析
bash
hostnamectl set-hostname master30.laoma.cloud # 永久主机名
echo "10.1.8.30 master30.laoma.cloud master30" >> /etc/hosts
# 其他节点类似
关键:主机名必须能通过 DNS 或 hosts 解析,否则 kubelet 会报错。
2. 容器运行时:containerd + nerdctl + crictl
2.1 安装 containerd
- 使用华为云 Docker 源安装
containerd.io(版本 1.7.20)。 - 生成默认配置:
containerd config default > /etc/containerd/config.toml - 必要修改 :
SystemdCgroup = true(让 containerd 使用 systemd 的 cgroup 驱动,与 kubelet 一致)。sandbox_image = "registry.k8s.io/pause:3.9"(K8s 的 pause 镜像版本)。- 镜像加速(CRI 层面):
toml
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://docker.m.daocloud.io", "https://docker.1ms.run"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
endpoint = ["https://k8s.m.daocloud.io", "https://registry.cn-hangzhou.aliyuncs.com/google_containers"]
- 重启:
systemctl restart containerd
2.2 nerdctl(类似 Docker CLI)
- 下载
nerdctl-1.7.7-linux-amd64.tar.gz,解压到/usr/bin。 - 配置 nerdctl 自身镜像加速(与 CRI 独立 ):在
/etc/containerd/certs.d/docker.io/hosts.toml设置。 - 重要 :K8s 使用 containerd 的
k8s.io命名空间,务必设置环境变量:
bash
export CONTAINERD_NAMESPACE=k8s.io
# 可写入 /etc/profile 或 ~/.bashrc
常用 nerdctl 命令对比 Docker:
| 操作 | Docker 命令 | nerdctl 命令 |
|---|---|---|
| 查看容器 | docker ps -a |
nerdctl ps -a |
| 运行容器 | docker run -d nginx |
nerdctl run -d nginx |
| 进入容器 | docker exec -it <id> bash |
nerdctl exec -it <id> bash |
| 查看日志 | docker logs <id> |
nerdctl logs <id> |
| 查看镜像 | docker images |
nerdctl images |
| 构建镜像 | docker build -t . |
nerdctl build -t .(需 buildkit) |
| 查看网络 | docker network ls |
nerdctl network ls |
2.3 crictl(K8s 调试利器)
- 安装:
apt install cri-tools - 配置端点:
crictl config runtime-endpoint unix:///var/run/containerd/containerd.sock - 常用 crictl 命令:
bash
crictl pods # 列出所有 Pod(与 K8s 对应)
crictl ps -a # 列出所有容器(包括非运行)
crictl images # 查看镜像
crictl inspect <id> # 查看容器/Pod 详细状态
crictl logs <containerID> # 查看容器日志(类似 kubectl logs)
crictl exec <id> <cmd> # 进入容器执行命令
注意:crictl 直接与 containerd 的 CRI 接口交互,不依赖于 kubectl,非常适合排查节点上容器运行问题。
3. Kubernetes 集群部署(kubeadm)
3.1 安装 kubeadm/kubelet/kubectl
- 从阿里云 K8s 源安装指定版本(1.30.2)。
bash
apt install -y kubeadm=1.30.2-1.1 kubelet=1.30.2-1.1 kubectl=1.30.2-1.1
- 锁定版本(防止意外升级):
apt-mark hold kubeadm kubelet kubectl - 启动 kubelet:
systemctl enable --now kubelet(此时会反复重启,待集群初始化后会稳定)。
3.2 预拉取镜像(可选)
bash
kubeadm config images pull --kubernetes-version=v1.30.2 --image-repository registry.aliyuncs.com/google_containers
- 这样可以避免初始化时因网络问题卡住。
3.3 初始化集群(Master 节点)
bash
kubeadm init \
--kubernetes-version=v1.30.2 \
--pod-network-cidr=10.224.0.0/16 \
--image-repository registry.aliyuncs.com/google_containers \
--apiserver-advertise-address=10.1.8.30 # 若多网卡,指定主 IP
各参数含义:
--pod-network-cidr:Pod 的 IP 段,必须与后续安装的网络插件(如 Calico)保持一致。--apiserver-advertise-address:Master 节点向其他节点通告的 IP,若不指定,会自动选择默认网关所在网卡的 IP。--service-cidr(默认 10.96.0.0/12):Service 的 IP 段,一般保持默认。
成功输出:
- 提示如何配置 kubectl。
- 给出
kubeadm join命令,用于添加 Worker 节点(务必保存)。
3.4 配置 kubectl 凭据
bash
mkdir -p $HOME/.kube
cp /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
- 也可以使用环境变量:
export KUBECONFIG=/etc/kubernetes/admin.conf,但推荐持久化到~/.kube/config。
3.5 安装网络插件(Calico)
- 下载清单:
bash
wget https://raw.githubusercontent.com/projectcalico/calico/v3.30.7/manifests/calico.yaml
- 修改 Pod CIDR :因为默认 Calico 使用
192.168.0.0/16,必须改为初始化时指定的10.224.0.0/16。
bash
sed -i 's|# - name: CALICO_IPV4POOL_CIDR|- name: CALICO_IPV4POOL_CIDR|' calico.yaml
sed -i 's|# value: "192.*| value: "10.224.0.0/16"|' calico.yaml
- 所有节点提前拉取镜像(避免启动时拉取慢):
bash
nerdctl pull docker.io/calico/cni:v3.30.7
nerdctl pull docker.io/calico/node:v3.30.7
nerdctl pull docker.io/calico/kube-controllers:v3.30.7
- 应用:
kubectl apply -f calico.yaml - 观察 Pod 状态:
kubectl get pods -n kube-system -w,等待所有 Pod 进入 Running。
3.6 加入 Worker 节点
- 在 Worker 节点上,使用初始化输出的 join 命令执行。若 token 过期,在 Master 上重新生成:
bash
kubeadm token create --print-join-command
- 执行后,Worker 会自动向 Master 注册,并在稍后变为 Ready(需等待网络插件生效)。
3.7 验证集群
bash
kubectl get nodes # 所有节点状态为 Ready
kubectl get pods -n kube-system # 所有 Pod 都为 Running
kubectl get cs # 查看控制组件健康状态(v1.24+ 可能不显示)
kubectl cluster-info # 查看集群信息
4. 节点与集群管理
4.1 节点维护(驱逐与删除)
- 将节点设为不可调度(cordon):
kubectl cordon worker31 - 驱逐 Pod(drain):
kubectl drain worker31 --ignore-daemonsets --delete-emptydir-data--ignore-daemonsets:忽略 DaemonSet 管理的 Pod(如 Calico、kube-proxy)。--delete-emptydir-data:删除使用 emptyDir 的 Pod(需谨慎)。
- 删除节点:
kubectl delete node worker31 - 在 Worker 节点上重置:
kubeadm reset -f(清理 K8s 状态,之后可重新加入)。
4.2 集群删除与重建
- 删除步骤 :
- 驱逐并删除所有 Worker 节点。
- 在 Worker 上执行
kubeadm reset -f。 - 在 Master 上执行
kubeadm reset -f,并删除~/.kube目录。 - 清理 CNI 配置:
rm -rf /etc/cni/net.d(可选)。
- 重建:直接再次
kubeadm init,注意使用相同的--pod-network-cidr,否则网络插件需重新配置。
4.3 备份与恢复集群配置
- 备份关键配置:
kubectl get cm -n kube-system kubeadm-config -o yaml > kubeadm-config-backup.yaml - 该文件包含了集群初始化参数,可用于重建时使用
--config指定,避免参数遗漏。
4.4 管理 Node 标签与污点(Taint)
- 打标签:
kubectl label node worker31 node-type=worker - 查看标签:
kubectl get nodes --show-labels - 添加污点(阻止 Pod 调度):
kubectl taint nodes master30 node-role.kubernetes.io/control-plane:NoSchedule - 删除污点:
kubectl taint nodes master30 node-role.kubernetes.io/control-plane:NoSchedule-
5. Namespace 与 Context 切换
5.1 Namespace 基本操作
bash
kubectl create ns my-ns
kubectl get ns
kubectl describe ns my-ns
kubectl delete ns my-ns # 会删除该 ns 下所有资源,谨慎!
- 资源对象默认属于
defaultns;系统组件属于kube-system。
5.2 切换当前 Namespace(原生 kubectl)
bash
kubectl config set-context --current --namespace=my-ns
kubectl config get-contexts # 查看当前 context 的 namespace 列
5.3 使用 kubens 高效切换
- 安装 kubens(来自 kubectx 项目):
bash
# 下载并解压
wget https://codeload.github.com/ahmetb/kubectx/zip/refs/heads/master -O kubectx.zip
unzip kubectx.zip
cp kubectx-master/kubens /usr/local/bin/
chmod +x /usr/local/bin/kubens
- 用法:
bash
kubens # 列出所有 ns,当前用 * 标记
kubens kube-system # 切换到 kube-system
kubens - # 切换到前一个 ns
kubens -c # 显示当前 ns
5.4 自定义 kns 脚本(课堂示例)
- 功能:无参显示所有 ns;一个参数则切换(并校验存在性)。
- 可放在
/usr/local/bin/并使用,与 kubens 互补。
6. 多集群管理
6.1 ~/.kube/config 文件结构
- clusters:每个集群的 API Server 地址、CA 证书。
- users:客户端身份认证(证书+私钥,或 token)。
- contexts:将集群和用户绑定,并可指定默认 namespace。
- current-context:当前使用的上下文。
6.2 查看与切换(原生 kubectl)
bash
kubectl config get-contexts # 列出所有 context
kubectl config current-context # 显示当前
kubectl config use-context <context名>
6.3 使用 kubectx 工具
- 安装方式同 kubens,
cp kubectx-master/kubectx /usr/local/bin/。 - 用法:
bash
kubectx # 列出所有 context,当前带 *
kubectx <name> # 切换
kubectx - # 切回上一个
kubectx -c # 显示当前
kubectx -u # 取消 current-context 设置
6.4 合并多个集群配置文件
bash
# 备份原有
cp ~/.kube/config ~/.kube/config.bak
# 合并(假设有另一份 /root/kubeconfig-prod)
export KUBECONFIG=~/.kube/config:/root/kubeconfig-prod
kubectl config view --flatten > ~/.kube/merged
mv ~/.kube/merged ~/.kube/config
- 之后
kubectx会识别所有 context,轻松切换。
6.5 通过环境变量临时切换
bash
export KUBECONFIG=/path/to/another/config
kubectl get nodes # 使用临时配置
7. 常用资源操作(快速入门)
7.1 Pod 管理
bash
kubectl run nginx --image=nginx --restart=Never # 创建独立 Pod
kubectl get pods -o wide # 查看 Pod 及 IP 节点
kubectl logs -f nginx # 查看日志
kubectl exec -it nginx -- /bin/bash # 进入容器
kubectl delete pod nginx
7.2 Deployment(无状态应用)
bash
kubectl create deployment web --image=nginx --replicas=3
kubectl scale deployment web --replicas=5 # 扩缩容
kubectl set image deployment web nginx=nginx:1.25 # 滚动更新
kubectl rollout status deployment web # 查看更新状态
kubectl rollout undo deployment web # 回滚
7.3 Service(服务暴露)
bash
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
kubectl get svc # 查看 NodePort 端口
curl http://<任意节点IP>:<NodePort>
7.4 ConfigMap 与 Secret(配置管理)
bash
# 创建 ConfigMap(键值对)
kubectl create cm app-config --from-literal=DB_HOST=mysql
# 创建 Secret(敏感信息,值需 base64 编码)
kubectl create secret generic db-password --from-literal=password=123456
# 在 Pod 中引用(环境变量或 volume)
7.5 Ingress(HTTP 路由)
- 需要安装 Ingress Controller(如 nginx-ingress),课堂未详述,但生产常用。
8. 存储管理(PV/PVC)
- Kubernetes 使用 PersistentVolume(PV)和 PersistentVolumeClaim(PVC)管理持久化存储。
- 常用存储类型:hostPath、NFS、Ceph、云盘等。
- 示例:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- Pod 中通过
volumes挂载 PVC。
9. 调度与亲和性
- 节点亲和性:
nodeSelector、nodeAffinity。 - Pod 亲和/反亲和:
podAffinity、podAntiAffinity。 - 污点(Taints)与容忍(Tolerations):控制哪些 Pod 可以调度到特定节点。
10. 监控与日志
- 常用命令:
bash
kubectl top nodes # 节点资源(需 metrics-server)
kubectl top pods -n <ns>
kubectl describe node <node> # 查看节点资源分配、事件
kubectl describe pod <pod> # 查看 Pod 事件、状态
- 集群事件查看:
kubectl get events -A --sort-by='.metadata.creationTimestamp' - 日志聚合:可部署 EFK(Elasticsearch+Fluentd+Kibana)或 Loki。
11. 常见故障排查指南
11.1 节点 NotReady
- 原因:kubelet 未启动、网络插件未部署、内核参数未设置、swap 未关闭。
- 排查:
systemctl status kubelet查看错误日志。journalctl -u kubelet -f实时查看。- 确认
swapoff -a已执行。 - 检查网络插件 Pod 是否 Running。
11.2 Pod 一直 Pending
- 原因:资源不足(CPU/内存)、节点污点不匹配、PVC 未绑定。
- 排查:
kubectl describe pod <pod>查看事件,会明确提示原因。
11.3 镜像拉取失败(ImagePullBackOff)
- 检查镜像名称和 tag 是否正确。
- 确认 containerd 能否拉取该镜像:
nerdctl pull <image>。 - 检查镜像加速配置是否生效。
11.4 Service 无法访问
- 检查 Service 的 selector 是否匹配 Pod 标签。
- 确认 Pod 的端口是否正确暴露(containerPort)。
- 若 NodePort 无法访问,检查防火墙/安全组是否放行端口。
11.5 证书过期(kubeadm)
- 查看证书过期时间:
kubeadm certs check-expiration - 更新所有证书:
kubeadm certs renew all - 重启控制平面组件(需重启 apiserver 等静态 Pod)。
11.6 etcd 问题
- etcd 是集群数据存储,若 etcd Pod 异常,集群将无法工作。
- 可查看 etcd 日志:
kubectl logs -n kube-system etcd-master30.laoma.cloud
12. 集群升级(概要)
- 升级控制平面:
kubeadm upgrade plan查看可用版本,然后kubeadm upgrade apply v1.31.0 - 升级节点:在 Worker 上
kubeadm upgrade node - 升级 kubectl 和 kubelet 到对应版本。
- 注意:升级前务必备份 etcd 数据!
13. 安全与 RBAC
- Kubernetes 使用 RBAC(基于角色的访问控制)管理权限。
- 核心对象:Role/ClusterRole (权限集合)、RoleBinding/ClusterRoleBinding(绑定到用户或 ServiceAccount)。
- 示例:创建只读 default 命名空间的角色。
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- 绑定到用户
alice:kubectl create rolebinding alice-pod-reader --role=pod-reader --user=alice -n default
14. 常用自动化命令生成(补全)
- 设置 kubectl 自动补全(永久生效):
bash
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc
15. 总结
- 掌握基础环境(Ubuntu 网络、内核、容器运行时)是稳定 K8s 的基石。
kubeadm是官方推荐的标准部署工具,搭配 Calico 等 CNI 插件即可构建生产级集群。- 熟练使用
kubectl、kubens/kubectx可极大提高日常运维效率。 - 多集群管理通过
~/.kube/config或KUBECONFIG环境变量实现,切换流畅。 - 故障排查时,善用
describe、logs和crictl等工具,结合事件日志快速定位。
建议:多动手实操,逐条命令敲一遍,理解每个步骤的意义,才能从容应对生产环境的问题。