
当您的应用程序增长时,仅仅使用 docker run 或 docker-compose up 运行容器已经不够了。您需要一个能够自动分配负载、自动重新启动崩溃的容器以及零停机时间部署更新的系统——这正是 Kubernetes 所做的。
本文从头开始解释 Kubernetes。无论您是刚刚了解容器的开发人员,还是准备在 VPS 上进行实验的 DevOps 工程师,您都会在这里找到明确的前进方向。
前置条件:熟悉 Docker 和容器的概念会有所帮助。如果您对 Docker 完全陌生,请先阅读什么是 Docker?。
什么是 Kubernetes?
Kubernetes(发音为"koo-ber-net-eez")——也称为 K8s ——是一个开源容器编排平台,最初由 Google 开发,现在由云原生计算基金会 (CNCF) 维护。
简单来说,Kubernetes 充当"容器管理器",它决定您的容器在哪台机器上运行、应该运行多少份副本,并确保它们始终准备好处理流量。
名称来源:"Kubernetes" 来自希腊语,意思是"舵手"或"船长"——反映了它在指导所有容器朝正确方向发展中的作用。
Kubernetes 解决的问题
想象您有一个运行 3 个容器的 Web 应用程序在单个 VPS 上运行。突然流量激增,其中一个容器因为内存不足而崩溃:
- Docker Compose 无法帮助——容器保持关闭,直到您手动重启它。
- 扩展到 5 个容器需要手动干预——没有自动化。
- 部署新版本而不停机需要仔细的手动协调。
Kubernetes 通过以下方式解决了所有这些问题:
- 自我修复:如果容器崩溃,Kubernetes 会立即重新启动它。
- 自动扩展:根据 CPU/内存负载自动添加或删除容器。
- 滚动更新:一次更新一个容器,零停机时间。
- 负载均衡:在所有运行的容器之间均匀分配传入流量。
您需要了解的核心概念
1. 集群 (Cluster)
一个集群是一组在 Kubernetes 下一起工作的机器 (Node)。每个集群都有一个控制平面(中央大脑)和一个或多个工作节点(容器实际运行的地方)。
2. 节点 (Node)
一个节点是集群中的单台机器——可以是 VPS 或物理服务器。有两种类型:
- 控制平面节点:管理整个集群并决定每个 Pod 在哪个节点上运行。
- 工作节点:按照控制平面的指示执行 Pod。
3. Pod
一个Pod 是 Kubernetes 中最小的可部署单元。它包含一个或多个容器(通常每个 Pod 一个容器)。每个 Pod 都有自己的 IP 地址,同一 Pod 中的所有容器共享网络命名空间。
4. 部署 (Deployment)
一个部署是一个模板,告诉 Kubernetes:"我需要这个 Pod 的副本始终运行 X 个。" 如果 Pod 崩溃,部署会立即创建一个替换 Pod。
5. 服务 (Service)
一个服务提供了一个稳定的 IP 地址和 DNS 名称来访问您的 Pod。因为 Pod IP 可能会改变,服务充当一致的入口点,将传入流量路由到正确运行的 Pod。
Kubernetes vs Docker Compose ——关键差异
大多数 Docker 用户从 Docker Compose 开始。这两个工具都管理容器,但它们适合于非常不同的场景:
| 特性 | Docker Compose | Kubernetes |
|---|---|---|
| 机器 | 单台机器 | 多台机器(多节点) |
| 自我修复 | 否(仅 restart: always) | 是——自动创建新 Pod |
| 自动扩展 | 否 | 是(HPA) |
| 滚动更新 | 必须停止并重启 | 零停机滚动更新 |
| 负载均衡 | 基础(手动 Nginx) | 内置 |
| 复杂性 | 低 | 高(学习曲线) |
| 最适合 | 开发/测试、小型生产 | 中等到大规模生产 |
Helm:Kubernetes 的包管理器
Helm 是 Kubernetes 的包管理器——类似于 Ubuntu 上的 apt 或 Python 中的 pip。Helm 让您可以使用单条命令安装复杂应用程序,而不是编写数十个 YAML 文件来部署应用程序。
Helm 如何工作
Helm 使用"Chart"的概念——具有可配置默认值的 YAML 模板包集:
| 概念 | 描述 | 类比 |
|---|---|---|
| Chart | 应用程序的 YAML 模板集 | 包 (.deb/.rpm) |
| Release | 集群上 Chart 的运行实例 | 已安装的进程 |
| Repository | Chart 的社区集合 | apt-get 存储库 |
| values.yaml | 用于自定义 Chart 设置的文件 | 配置文件 |
安装 Helm 并开始使用
# 在 Linux 上安装 Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# 添加官方 Helm 存储库
helm repo add stable https://charts.helm.sh/stable
helm repo update
# 使用单条命令安装 Nginx 入站控制器
helm install my-nginx ingress-nginx/ingress-nginx
# 列出已安装的发行版
helm list
# 卸载
helm uninstall my-nginx
在部署具有许多组件的应用程序时,Helm 节省了大量时间。例如,在 Kubernetes 上部署 WordPress 需要 Deployment、Service、PersistentVolume、ConfigMap 和 Secret——Helm 在一条命令中处理所有这些。
谁应该使用 Kubernetes?
Kubernetes 并不适合所有项目。在以下情况下使用它是有意义的:
- 微服务架构:应用程序分为许多独立服务(API、身份验证、通知等)。
- 不可预测的流量:需要根据负载自动向上或向下扩展。
- 高可用性要求:即使一台机器出故障也无法容忍停机时间。
- 频繁的 CI/CD 部署:需要经常发布更新而不影响生产。
- 多个环境:开发、测试和生产运行在同一基础设施上。
⚠️ 不推荐用于:小型项目或仅运行 1-3 个容器的应用程序。Kubernetes 的运营开销明显高于 Docker Compose。如果您不真正需要它,Docker Compose 是更好的选择。
安全地管理 Secrets 和 ConfigMaps
Kubernetes 提供了两种专用资源类型用于管理与容器镜像分离的配置。这使您的应用程序保持安全和灵活,而无需将凭据烘焙到 Docker 镜像中。
ConfigMap ——用于非敏感配置
使用 ConfigMaps 存储不需要保密的配置值,如服务 URL、功能标志和数据库名称:
# 从字面值创建 ConfigMap
kubectl create configmap app-config \
--from-literal=DB_HOST=mysql-service \
--from-literal=APP_ENV=production \
--from-literal=MAX_CONNECTIONS=100
# 检查 ConfigMap
kubectl describe configmap app-config
Secret ——用于敏感凭据
使用 Secret 存储不应该出现在源代码中的密码、API 密钥和令牌。Kubernetes 存储 Base64 编码的 Secret(启用静态加密以获得更强的保护):
# 创建 Secret
kubectl create secret generic db-credentials \
--from-literal=DB_PASSWORD=MyStr0ngP@ss \
--from-literal=DB_USER=appuser
# 检查(值将是 Base64 编码)
kubectl get secret db-credentials -o yaml
在 Pod 内使用 ConfigMap 和 Secret
# 使用 ConfigMap 和 Secret 的 Deployment 示例
spec:
containers:
- name: myapp
image: myapp:latest
envFrom:
- configMapRef:
name: app-config # 从 ConfigMap 加载所有密钥
- secretRef:
name: db-credentials # 加载 Secret 作为环境变量
安全警告:切勿直接将 Secret 值提交到 Git 存储库。通过 kubectl 直接在集群上创建 Secret,或使用与 Kubernetes 集成的外部 Secret 管理器(如 HashiCorp Vault)来处理生产工作负载。
在 VPS 上开始使用 k3s
k3s 是由 Rancher Labs 开发的轻量级、生产级 Kubernetes 发行版。它仅使用约 512MB 的 RAM 并在单条命令中安装——完美用于在 VPS 上进行实验。
系统要求
- 运行 Ubuntu 20.04 或 22.04 的 VPS(建议 ≥1GB RAM)
- Root 或 sudo 访问权限
- 为 Kubernetes API 开放端口 6443
步骤 1 ——安装 k3s
运行一条命令来安装 k3s 并启动您的第一个控制平面节点:
curl -sfL https://get.k3s.io | sh -
验证安装:
sudo systemctl status k3s sudo kubectl get nodes
如果您的 Node 显示 Ready 状态,则 k3s 正在成功运行。
步骤 2 ——部署测试应用程序(Nginx)
创建 Deployment YAML 文件:
# nginx-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo spec: replicas: 3 # 始终保持 3 个 Pod 运行 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80
sudo kubectl apply -f nginx-deployment.yaml
检查所有三个 Pod 是否正在运行:
sudo kubectl get pods
您应该看到 3 个 Pod 处于 Running 状态。
步骤 3 ——使用 Service 公开应用程序
# nginx-service.yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: NodePort selector: app: nginx ports: - port: 80 targetPort: 80 nodePort: 30080 # 可在 http://YOUR_VPS_IP:30080 访问
sudo kubectl apply -f nginx-service.yaml
打开浏览器并导航到 http://YOUR_VPS_IP:30080。响应由 3 个运行的 Pod 之一自动提供。
步骤 4 ——测试自我修复
手动删除一个 Pod 并观察 Kubernetes 重新创建它:
# 列出 Pod 并复制 Pod 名称 sudo kubectl get pods # 删除一个 Pod(替换为实际的 Pod 名称) sudo kubectl delete pod nginx-demo-xxxxxxx-xxxxx # 观察替代 Pod 被创建 sudo kubectl get pods
在几秒钟内,Kubernetes 会将 Pod 计数恢复到 3。这就是自我修复的实际应用。
什么是 kubectl? kubectl(发音为"kube-control")是用于管理 Kubernetes 中所有内容的命令行工具——部署应用程序、扩展、检查日志和删除资源。
使用 Prometheus 和 Grafana 监控 Kubernetes
监控对于任何生产 Kubernetes 集群都至关重要。Prometheus(用于收集指标)和 Grafana(用于可视化)形成 Kubernetes 生态系统中最广泛采用的监控堆栈。
Kubernetes 中要监控的关键指标
- Pod CPU/内存使用情况:识别消耗过多资源或被 OOMKilled 的 Pod。
- 节点资源利用率:每个节点的 CPU、RAM 和磁盘使用情况。
- Pod 重启计数:频繁重启通常表示存在潜在问题。
- API 服务器延迟:Kubernetes 控制平面的响应时间。
- 网络 I/O:每个 Pod 的入站和出站流量量。
使用 Helm 安装 kube-prometheus-stack
获得完整监控设置的最快方式是使用社区 Helm Chart,它捆绑了 Prometheus、Grafana 和 AlertManager 以及预构建的 Kubernetes 仪表板:
# 添加 Prometheus 社区 Helm 存储库
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# 安装 kube-prometheus-stack
helm install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace
# 验证 Pod 正在运行
kubectl get pods -n monitoring
# 通过 port-forward 访问 Grafana
kubectl port-forward -n monitoring \
svc/monitoring-grafana 3000:80
在浏览器中打开 http://localhost:3000。使用用户名 admin 和从 Secret 检索的密码登录:
kubectl get secret -n monitoring monitoring-grafana \
-o jsonpath="{.data.admin-password}" | base64 --decode
k3s 兼容性说明:在 k3s 上运行时,将这些标志添加到安装命令中:--set kubeEtcd.enabled=false --set kubeScheduler.enabled=false --set kubeControllerManager.enabled=false。k3s 的组件打包方式与标准 Kubernetes 不同。
Kubernetes 架构一览
一个 Kubernetes 集群由几个关键组件组成:
- kube-apiserver:集群的前门——所有请求都通过它。
- etcd:存储整个集群状态的键值数据库。
- kube-scheduler:决定新 Pod 应该在哪个节点上运行。
- kube-controller-manager:确保 Deployment 始终拥有正确数量的 Pod。
- kubelet:每个工作节点上执行控制平面指令的代理。
- kube-proxy:管理每个工作节点上的网络路由规则。
滚动更新和安全回滚
Kubernetes 最强大的功能之一是能够在没有任何停机时间的情况下更新应用程序,如果出现问题,可以在几秒钟内回滚到之前的版本。
执行滚动更新
将容器镜像更新为新版本:
# 更新 Deployment 镜像
kubectl set image deployment/nginx-demo \
nginx=nginx:1.25 \
--record
# 实时观看推出状态
kubectl rollout status deployment/nginx-demo
# 查看完整的推出历史
kubectl rollout history deployment/nginx-demo
在滚动更新期间,Kubernetes 一次替换一个 Pod(根据配置的策略)。它等待每个新 Pod 就绪后再删除旧的 Pod,确保持续的服务可用性。
出现问题时回滚
# 立即回滚到之前的版本
kubectl rollout undo deployment/nginx-demo
# 回滚到特定的版本(例如版本 2)
kubectl rollout undo deployment/nginx-demo --to-revision=2
# 验证回滚是否成功
kubectl get pods -l app=nginx
配置更新策略
通过 Deployment YAML 中的 strategy 字段控制更新行为:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 同时可能不可用的最大 Pod 数
maxSurge: 1 # 副本计数上方允许的最大额外 Pod 数
最佳实践:始终在测试集群上测试部署,然后再提升到生产环境。使用 --record 标志维护推出历史,让您的团队可以看到谁部署了什么以及何时部署的。
推荐的学习路径
如果您刚刚开始,按顺序按照以下步骤进行:
- 首先掌握 Docker——理解容器、镜像、卷和网络。
- 在单个 VPS 上尝试 k3s——按照本文的动手步骤进行。
- 学习 YAML Manifest:Deployment、Service、ConfigMap、Secret。
- 升级到托管 Kubernetes:准备好后,像 EKS、GKE 或 AKS 这样的平台会自动为您管理控制平面。
Kubernetes 的 VPS:k3s 最少需要约 512MB 的 RAM,但建议使用 1-2GB 以获得舒适的体验。对于真实生产中的多节点集群,每个节点至少需要规划 2GB 的 RAM。
完全根访问 VPS ——为 Kubernetes 做好准备
使用完整的服务器控制安装 k3s、Docker 和任何 DevOps 工具。VPS 计划从 500 泰铢/月起。地点:泰国、新加坡。
查看 VPS 套餐