从入门到实战:Kubernetes完全指南——概念、架构、集群部署与Dashboard可视化

一、为什么需要Kubernetes?------从痛苦到解放

1.1 没有K8s的日子

假如你是一家电商公司的运维。最开始只有一个"用户服务",用Docker跑在一台服务器上,很舒服。

后来加了"订单服务""支付服务""库存服务""推荐服务"......每个服务为了高可用,至少要跑3个副本。

然后噩梦开始了:

  • 服务器宕机:某台物理机突然挂了,上面跑的十几个容器全部消失,需要人工去其他机器上重新启动。

  • 流量突增:双11来了,订单服务需要从3个副本扩容到30个,你得一台一台机器去拉镜像、启动容器,再配置负载均衡。

  • 版本更新:新上线一个功能,需要滚动更新(先启动新版本,等稳定后再停旧版本),手动操作极易出错,且回滚麻烦。

  • 服务发现:每个容器重启后IP会变,A服务怎么知道B服务的地址?用固定的宿主机端口?端口冲突怎么办?

  • 资源利用不均:有的机器CPU跑满,有的机器空闲,但又不能自动把容器搬过去。

这些问题Docker本身解决不了------Docker是"单机容器引擎",它只管"在一台机器上把容器跑起来"。

Kubernetes(K8s) 就是来统一解决以上所有问题的:它把多台服务器变成一个统一的"资源池",你只需要告诉它"我要跑什么、跑几个",剩下的调度、伸缩、修复、服务发现全部自动完成

1.2 K8s能做什么?

  • 自动部署与回滚:支持滚动更新,可以一键回滚到上一版本。

  • 弹性伸缩:根据CPU使用率或自定义指标,自动增加或减少Pod数量。

  • 服务发现与负载均衡:每个服务有一个固定的虚拟IP和DNS名,自动把流量分发到后端Pod。

  • 自我修复:如果某个Pod挂了,Controller会马上拉起一个新的;节点宕机后,会在其他健康节点上重建Pod。

  • 存储编排:自动挂载持久化存储(本地、NFS、云盘等),Pod漂移时存储也跟着迁移。

  • 配置管理:通过ConfigMap和Secret管理配置和密码,无需重新打包镜像。


二、Kubernetes核心概念------用最简单的话说清楚

概念 一句话解释 现实类比
Pod K8s里最小的部署单元,一个Pod里可以有一个或多个容器(通常一个Pod一个容器)。 一个"豆荚"里可以有一颗或多颗豆子。
Deployment 管理一组相同的Pod,负责滚动更新、扩缩容、回滚。 生产线的班长,决定开几条流水线,怎么换新设备。
Service 为一组Pod提供固定的访问入口(VIP和DNS),做负载均衡。 餐厅的"叫号台",客人不知道后厨哪个厨师在做菜,统一找叫号台就行。
Namespace 将集群内部资源"隔离"成多个虚拟集群,用于区分环境(dev/test/prod)或团队。 办公楼的楼层,研发部在5楼,财务部在6楼,互不干扰。
Ingress 七层(HTTP/HTTPS)路由,通过域名和路径把外部流量转发到不同的Service。 商场总服务台,根据你想去的店铺名(域名)引导你去相应楼层。
ConfigMap 存储配置信息(非敏感),可以挂载到Pod中变成环境变量或文件。 工地上的"图纸",工人按图纸施工。
Secret 存储敏感信息(密码、token),类似ConfigMap但会做base64编码。 保险柜,只有授权人能打开。
Volume 存储卷,Pod内挂载的磁盘,可以是临时、宿主机目录、网络存储等。 U盘,拔下来插到另一台电脑还能用(如果支持)。
Node 工作节点,可以是物理机或虚拟机,负责运行Pod。 工厂里的工人,干活的。
Master 控制平面,包含API Server、Scheduler等组件,管理所有Node。 工厂厂长、调度员、监控室。

2.1 为什么要有Pod?

很多人第一次学K8s会疑惑:为什么不直接管理容器,还要弄个Pod?

因为有些容器需要紧密协作:比如一个容器写日志,另一个容器收集日志;或者一个容器做代理,另一个容器是实际服务。如果把它们放在同一个Pod里,它们可以共享同一个IP和存储卷,通过localhost通信,非常高效。

2.2 Deployment vs StatefulSet vs DaemonSet

类型 适用场景 特点
Deployment 无状态应用(Web前端、API) Pod名随机,顺序无关,可随意替换
StatefulSet 有状态应用(数据库、消息队列) Pod有固定名称(如mysql-0, mysql-1),顺序启停,每个Pod可挂载独立存储
DaemonSet 每个节点都要运行的守护进程(监控agent、日志收集、网络插件) 新节点加入自动部署一个Pod

三、Kubernetes集群架构详解(看懂这张图就懂了一半)

text

复制代码
+---------------------------------------------------------------+
|                         Master Node                           |
|  +-------------------+  +------------------+  +-------------+ |
|  |   API Server      |  |   Scheduler      |  | Controller  | |
|  | (集群入口,认证)   |  | (调度Pod到Node)  |  |  Manager    | |
|  +-------------------+  +------------------+  | (维持期望状态)| |
|                                                  +-------------+ |
|  +-------------------------------------------------------------+ |
|  |                      etcd (集群状态存储)                     | |
|  +-------------------------------------------------------------+ |
+---------------------------------------------------------------+
                              |
                              | (API调用)
                              ↓
+---------------------------------------------------------------+
|                         Worker Node 1                          |
|  +------------------+  +------------------+  +--------------+ |
|  |     kubelet      |  |   kube-proxy     |  | Container    | |
|  | (管理Pod生命周期) |  | (网络规则/负载均衡)|  |  Runtime     | |
|  +------------------+  +------------------+  | (如Docker)    | |
|                                              +--------------+ |
|  +---------------------------------------------------------+   |
|  |  Pod A |  Pod B |  Pod C ...                           |   |
|  +---------------------------------------------------------+   |
+---------------------------------------------------------------+
+
同样结构的 Worker Node 2, 3...

3.1 各个组件是干什么的?(理解即可,不用背)

Master组件

  • API Server :一切操作的入口,无论是kubectl命令还是内部组件,都通过它通信。它负责认证、授权、准入控制。

  • Scheduler:当你要创建一个Pod时,Scheduler会看哪个Node资源够用(CPU、内存、亲和性等),然后把Pod"绑定"到那个Node上。

  • Controller Manager:里面有很多控制器(Deployment Controller、Node Controller等)。它们不断检查"当前状态"是否等于"你期望的状态",如果不相等就采取行动(比如重启挂了的Pod)。

  • etcd :分布式键值存储,保存集群的所有配置和状态(有哪些Node、Pod、Service等)。高可用必备,一般部署3个或5个奇数节点。

Node组件

  • kubelet:每个Node上的"管家",接收API Server的指令,负责创建、停止、监控Pod;上报Node和Pod状态。

  • kube-proxy:维护节点上的网络规则(iptables/IPVS),实现Service的虚拟IP和负载均衡。

  • 容器运行时:真正跑容器的引擎,如Docker、containerd、CRI-O。Kubelet通过CRI接口与它交互。

四、环境准备(所有节点执行)

实验环境

主机名 IP 地址 操作系统 配置
k8s-master 192.168.10.101 CentOS 7.9 / Rocky Linux 8 2核4G
k8s-node1 192.168.10.102 CentOS 7.9 / Rocky Linux 8 2核2G
k8s-node2 192.168.10.103 CentOS 7.9 / Rocky Linux 8 2核2G

所有操作使用 root 用户,或使用 sudo。确保节点之间网络互通,可访问互联网。

4.1 基础配置(三台都做)

bash

复制代码
# 1. 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 2. 关闭 SELinux
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

# 3. 关闭 swap(K8s 强制要求)
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab

# 4. 修改主机名(分别执行)
# Master:
hostnamectl set-hostname k8s-master
# Node1:
hostnamectl set-hostname k8s-node1
# Node2:
hostnamectl set-hostname k8s-node2

# 5. 配置 hosts(所有节点)
cat >> /etc/hosts <<EOF
192.168.10.101 k8s-master
192.168.10.102 k8s-node1
192.168.10.103 k8s-node2
EOF

# 6. 加载内核模块
cat > /etc/modules-load.d/k8s.conf <<EOF
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter

# 7. 优化内核参数
cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
sysctl --system

# 8. 时间同步
yum install -y chrony
systemctl enable --now chronyd
chronyc sources

五、安装容器运行时(containerd),前面有搭建docker的步骤根据自己的情况选择

containerd和docker对比:

  • 开发阶段 (你现在做的事)依然用Docker 。你用docker build命令打包出来的镜像,是整个行业标准(OCI标准)。

  • 生产阶段 (K8s做的事)实际运行时并不再是Docker 。K8s会拉取你刚才用Docker打包好的镜像,然后调用轻量的containerd来运行这个镜像。

  • 一句话总结 :Docker在生产环境中从 "车轮" (运行容器)的角色,变成了 "图纸" (构建镜像标准)的角色。containerd则从幕后走向前台,成为那只看似没动、实则日夜狂奔的"车轮"。

K8s 1.24 之后移除了 dockershim,官方推荐使用 containerd,它支持 OCI 镜像(包括 Docker 镜像),且性能更好。我们安装 containerd。

bash

复制代码
# 添加 containerd 的 yum 源(阿里云)
yum install -y yum-utils
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安装 containerd
yum install -y containerd.io

# 生成默认配置文件
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml

# 修改配置文件:将 SystemdCgroup 改为 true,并使用国内镜像加速
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sed -i 's|registry.k8s.io|registry.aliyuncs.com/google_containers|g' /etc/containerd/config.toml

# 配置镜像加速(可选,添加 docker.io 镜像)
cat >> /etc/containerd/config.toml <<EOF

[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
  endpoint = ["https://docker.m.daocloud.io", "https://docker.unsee.tech"]
EOF

# 启动 containerd
systemctl daemon-reload
systemctl enable --now containerd

# 验证
crictl version

注意:containerd 完全兼容 Docker 镜像,你可以继续用 docker build 构建镜像,然后用 ctrcrictl 管理。


六、安装 kubeadm、kubelet、kubectl

bash

复制代码
# 添加 K8s 阿里云源
cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
EOF

# 安装指定版本(使用 v1.28.2,当前主流)
yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2 --nogpgcheck

# 设置 kubelet 开机自启(暂时不会启动成功,需要初始化集群后才正常)
systemctl enable kubelet

七、初始化控制平面节点(Master)

7.1 预拉取镜像

bash

复制代码
kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers

7.2 创建初始化配置文件(推荐)

为了更清晰控制参数,我们使用配置文件方式:

bash

复制代码
cat > kubeadm-init.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.10.101   # 改为你的 Master IP
  bindPort: 6443
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.2
imageRepository: registry.aliyuncs.com/google_containers
controlPlaneEndpoint: "192.168.10.101:6443"
networking:
  podSubnet: 10.244.0.0/16      # 必须与网络插件一致
  serviceSubnet: 10.96.0.0/12
dns:
  type: CoreDNS
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
EOF
复制代码
7.3 执行初始化

bash

复制代码
kubeadm init --config=kubeadm-init.yaml --upload-certs

初始化成功后,最后几行会输出类似这样的 join 命令(务必保存):

bash

复制代码
kubeadm join 192.168.10.101:6443 --token xxxxx --discovery-token-ca-cert-hash sha256:xxxxx

7.4 配置 kubectl(让当前用户能操作集群)

bash

复制代码
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

# 验证
kubectl get nodes
# 输出 master 状态为 NotReady(网络插件未安装)

八、安装网络插件(Calico)

网络插件是实现 Pod 跨节点通信的关键。这里使用 Calico,性能好且支持网络策略。

bash

复制代码
# 安装 Tigera Operator(Calico 官方推荐方式)
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27/manifests/tigera-operator.yaml

# 下载 custom-resources.yaml 并修改 Pod CIDR
wget https://raw.githubusercontent.com/projectcalico/calico/v3.27/manifests/custom-resources.yaml
sed -i 's|192.168.0.0/16|10.244.0.0/16|g' custom-resources.yaml

# 应用配置
kubectl create -f custom-resources.yaml

# 等待所有 Pod 运行(约 2 分钟)
watch kubectl get pods -n calico-system
复制代码
所有 Pod 都为 Running 后,查看节点状态:

bash

复制代码
kubectl get nodes
# 应该变为 Ready

九、工作节点加入集群

k8s-node1k8s-node2 上执行前面保存的 kubeadm join 命令:

bash

复制代码
kubeadm join 192.168.10.101:6443 --token xxxxx --discovery-token-ca-cert-hash sha256:xxxxx

如果 token 过期,在 Master 上重新生成:

bash

复制代码
kubeadm token create --print-join-command

加入后回到 Master 验证:

bash

复制代码
kubectl get nodes
# 应该看到三个节点都是 Ready 状态

至此,K8s 集群搭建完成!🎉


十、验证集群健康

bash

复制代码
# 查看所有 Namespace 下的 Pod
kubectl get pods --all-namespaces

# 查看集群信息
kubectl cluster-info

# 查看组件状态
kubectl get componentstatuses

如果 CoreDNS 等 Pod 处于 Running 状态,说明集群正常。


十一、部署 Kubernetes Dashboard

Dashboard 是官方提供的 Web UI,方便管理集群。

11.1 安装 Dashboard

bash

复制代码
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

11.2 创建管理员用户

创建 dashboard-admin.yaml

复制代码
yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard

应用:

bash

复制代码
kubectl apply -f dashboard-admin.yaml

11.3 获取登录 Token

bash

复制代码
kubectl -n kubernetes-dashboard create token admin-user

复制输出的一长串 token。

11.4 暴露 Dashboard 服务(NodePort)

默认 Dashboard 的服务类型是 ClusterIP,仅集群内部访问。我们改为 NodePort 以便外部访问。

bash

复制代码
kubectl patch svc kubernetes-dashboard -n kubernetes-dashboard -p '{"spec":{"type":"NodePort"}}'

查看 NodePort 端口:

bash

复制代码
kubectl get svc -n kubernetes-dashboard

输出示例:

text

复制代码
NAME                        TYPE        CLUSTER-IP      PORT(S)         AGE
kubernetes-dashboard        NodePort    10.109.89.23    443:30088/TCP   2m

11.5 访问 Dashboard

浏览器访问:https://任意节点IP:30088(注意是 https)

  • 浏览器会提示"不安全",点击"高级" -> "继续前往"

  • 选择 "Token" 登录方式

  • 粘贴上面获取的 token,即可进入 Dashboard 管理界面。

你可以在这里查看所有 Namespace、Pod、Deployment、Service 等资源,甚至可以直接编辑 YAML。


十二、部署测试应用(Nginx)

创建一个 Deployment 和 Service 来验证集群功能。

创建 nginx-test.yaml

yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080   # 可选,范围 30000-32767

部署:

bash

复制代码
kubectl apply -f nginx-test.yaml

# 查看 Pod 分布
kubectl get pods -o wide

# 查看 Service 端口
kubectl get svc nginx-service

测试访问:http://任意节点IP:30080,应看到 Nginx 欢迎页面。


十三、必知必会的知识点补充

13.1 资源限制(Requests & Limits)

每个 Pod 都应配置资源请求和限制,防止某个 Pod 耗尽节点资源。

yaml

复制代码
resources:
  requests:
    memory: "128Mi"
    cpu: "200m"
  limits:
    memory: "256Mi"
    cpu: "500m"
  • requests:调度时保证的最小资源。

  • limits:容器运行时允许使用的最大资源。

13.2 滚动更新与回滚

bash

复制代码
# 更新镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.20 --record

# 查看更新历史
kubectl rollout history deployment/nginx-deployment

# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment

13.3 使用 ConfigMap 管理配置

bash

复制代码
# 创建 ConfigMap
kubectl create configmap app-config --from-literal=APP_ENV=prod

# 在 Pod 中引用(作为环境变量)
...
env:
- name: APP_ENV
  valueFrom:
    configMapKeyRef:
      name: app-config
      key: APP_ENV

13.4 持久化存储(PV/PVC)

生产环境建议使用 PV 和 PVC 对接 NFS、Ceph 或云存储。示例(hostPath 仅用于测试):

yaml

复制代码
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
# 在 Pod 中挂载
volumes:
- name: data
  persistentVolumeClaim:
    claimName: my-pvc

13.5 污点与容忍

Master 节点默认有一个污点:node-role.kubernetes.io/control-plane:NoSchedule,因此普通 Pod 不会调度到 Master 上。查看污点:

bash

复制代码
kubectl describe node k8s-master | grep Taint

给节点添加污点:

bash

复制代码
kubectl taint nodes node1 key=value:NoSchedule

Pod 添加容忍才能被调度到有污点的节点:

yaml

复制代码
tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"

13.6 节点亲和性

yaml

复制代码
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: disktype
          operator: In
          values:
          - ssd

13.7 常用排错命令

bash

复制代码
# 查看 Pod 详细事件
kubectl describe pod <pod-name>

# 查看 Pod 日志
kubectl logs <pod-name> [-c <container-name>]

# 进入容器
kubectl exec -it <pod-name> -- /bin/bash

# 查看集群事件
kubectl get events --all-namespaces --sort-by='.lastTimestamp'

# 查看节点资源使用(需要先安装 metrics-server)
kubectl top nodes
kubectl top pods

十四、常见问题排查

问题 可能原因 解决方法
kubectl get nodes 显示 NotReady 未安装网络插件 安装 Calico 或 Flannel
kubeadm init 拉取镜像失败 网络不通或镜像仓库不可达 使用阿里云镜像仓库 registry.aliyuncs.com/google_containers
节点加入失败,token 无效 token 过期 Master 上 kubeadm token create --print-join-command 重新获取
Pod 一直 Pending 资源不足或没有合适的节点 检查节点资源,增加节点或降低 Pod 资源请求
Service 的 ClusterIP 无法 ping 通 正常现象,ClusterIP 是虚拟 IP,只支持 TCP/UDP,不支持 ICMP 使用 curltelnet 测试端口
Dashboard 登录后无权限 使用的 token 权限不足 创建 cluster-admin 的 ServiceAccount 并获取 token
containerd 拉取镜像慢 未配置镜像加速 修改 /etc/containerd/config.toml 添加 registry.mirrors,重启 containerd

十五、总结与后续学习建议

恭喜!您已经完成了:

  • ✅ 理解 K8s 的核心价值与架构

  • ✅ 亲手搭建了一个 1 Master + 2 Node 的生产级集群(使用 containerd + Calico)

  • ✅ 部署了 Dashboard 可视化界面并成功登录

  • ✅ 运行了第一个 Nginx 应用并进行访问测试

  • ✅ 学习了资源限制、滚动更新、ConfigMap、存储、污点等关键知识点

下一步建议

  • 学习 Helm:用 Helm 打包和部署复杂应用(如 MySQL、Redis)。

  • 部署 Ingress Controller:使用 Nginx Ingress 实现域名路由和 HTTPS 自动证书。

  • 监控系统:搭建 Prometheus + Grafana 监控集群和应用。

  • 日志系统:EFK(Elasticsearch + Fluentd + Kibana)收集日志。

  • CI/CD:集成 GitLab CI 或 Jenkins,实现代码推送自动构建镜像并部署到 K8s。

  • 服务网格:了解 Istio,实现流量切分、熔断、灰度发布。

这份文档的所有命令都已经过实际测试,您可以直接复制粘贴到您的实验环境中使用。如果遇到问题,请对照"常见问题排查"部分解决。

相关推荐
爱学习 爱分享9 小时前
k8s 开启防火墙,容器内部无法访问外部 ip
tcp/ip·容器·kubernetes
珠海西格电力10 小时前
零碳园区的能源供给成本主要包括哪些方面?
大数据·分布式·微服务·架构·能源
神奇的程序员10 小时前
重构了自己5年前写的截图插件
前端·javascript·架构
Luhui Dev10 小时前
Anthropic 2026 最新 Agent Harness 架构完整拆解:Managed Agents
人工智能·架构·agent·luhuidev
叶帆10 小时前
【YFIOs】Docker方式部署
运维·docker·容器
小猿姐11 小时前
Clickhouse Kubernetes Operator 实测:哪种方案更适合生产?
运维·数据库·kubernetes
xifangge202511 小时前
【深度架构】Claude Code + Opus 4.6 全流程调优:API 路由重定向技术与 Agentic 编程流实战(附零成本接入方案)
架构·claudecode·opus4.6
岳来11 小时前
Docker 的 --privileged 特权模式学习
docker·容器·--privileged
闵孚龙12 小时前
Claude Code API通信层全解析:重试、流式、降级、Fast Mode、Prompt Cache 与 Files API 的底层工程
人工智能·架构·prompt