1. 容器化 (Containerization)
容器是现代云原生应用的标准交付单元。容器化将应用程序及其依赖环境(运行时、系统库、配置文件等)打包成一个自包含的不可变镜像,从而实现真正意义上的 “Build once, Run anywhere”。
容器与传统虚拟机的对比
| 维度 | 容器 (Containers) | 虚拟机 (Virtual Machines) |
|---|---|---|
| 虚拟化层级 | 操作系统级虚拟化 (共享 Host OS 内核) | 硬件级虚拟化 (通过 Hypervisor 模拟硬件) |
| 隔离机制 | Linux Namespaces (隔离) + Cgroups (限额) | 独立 Guest OS 内核与虚拟硬件隔离 |
| 资源开销 | 极低(MB 级内存,无额外系统底噪) | 较高(GB 级内存,运行整套操作系统) |
| 启动速度 | 毫秒至秒级 (普通进程启动) | 数十秒至分钟级 (完整系统引导启动) |
| 存储占用 | 小,基于 UnionFS / OverlayFS 分层复用 | 大,包含完整系统镜像文件 |
| 适用场景 | 微服务、高并发弹性扩缩容、CI/CD 自动化流水线 | 强隔离多租户、需要特定底层内核或异构操作系统 |
提示: 容器与虚拟机并不是非此即彼的对立关系。在生产实践中,公有云通常在底层通过高性能裸金属或轻量虚拟化(如 AWS Nitro、Firecracker MicroVM)构建物理计算池,再在上层调度运行容器,兼顾安全隔离与弹性效率。
容器编排 (Container Orchestration)
当微服务架构发展到成百上千个容器实例跨多台物理机/虚拟机运行时,单靠 docker run 或简单的自动化脚本已无法应对复杂拓扑。容器编排平台为此而生,核心解决以下问题:
- 自动化部署与扩缩容:基于 CPU/内存利用率或业务指标自动水平扩缩(HPA)。
- 服务发现与负载均衡:通过统一的 DNS 名称和 VIP 将流量分发至后端 Pod。
- 故障自愈 (Self-Healing):自动重启挂掉的容器、替换不可用节点上的实例并重新调度。
- 存储编排:自动挂载本地存储、公有云块存储(EBS/云硬盘)或网络文件系统(NFS/Ceph)。
- 声明式配置与机密管理:在不重新构建镜像的情况下管理配置(ConfigMap)和密码证书(Secret)。
- 金丝雀/灰度发布与回滚:渐进式更新应用版本,异常时一键回滚。
随着技术演进,Kubernetes (K8s) 已成为 CNCF(云原生计算基金会)事实上的全球工业标准。
容器运行时演进:从 Docker 到 CRI
自 Kubernetes v1.24 起,官方正式移除了旧有的 dockershim。目前 Kubernetes 通过标准的 CRI (Container Runtime Interface) 直接与现代容器运行时通信:
- containerd:工业级标准容器运行时(源自 Docker 核心组件,轻量、稳定)。
- CRI-O:专为 Kubernetes 打造的轻量级纯净 CRI 运行时。
开发者本地依然可以使用 Docker 进行镜像构建与测试,而集群底层 Pod 的生命周期则由 containerd/CRI-O 直接负责。
2. 现代化本地开发集群搭建
在本地学习和测试 Kubernetes 时,推荐采用轻量级集群工具,无需部署庞大沉重的生产集群。
常用本地环境选型
- Kind (Kubernetes in Docker) [强烈推荐]:将每个容器作为集群节点运行,跨平台支持极好,冷启动极快,是当前官方单元测试与 CI/CD 自动化验证的主流工具。
- Minikube:Kubernetes 官方推出的单/多节点学习工具,支持 VirtualBox、KVM、Docker 等多种驱动。
- k3s:Rancher 推出的超轻量级 K8s 发行版(单二进制仅数十兆),非常适合边缘计算、ARM 设备(树莓派等)和资源受限环境。
- MicroK8s:Canonical 维护的轻量级发行版,通过 snap 分发,深度集成 Ubuntu 生态。
使用 Kind 快速搭建本地集群
安装 Kind 与 kubectl
# 安装 Kind CLI (Linux amd64)
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.22.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# 安装 kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
创建带 Ingress 端口映射的本地多节点集群
创建 kind-cluster.yaml 配置文件:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: dev-cluster
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
- role: worker
启动集群:
# 创建集群
kind create cluster --config kind-cluster.yaml
# 验证节点状态
kubectl get nodes -o wide
将本地编译好的镜像直接载入 Kind 集群(免去推送到远程仓库的等待):
kind load docker-image my-app:v1 --name dev-cluster
备选:MicroK8s 极速初始化、零资源占用与网络排坑指南 (Ubuntu Snap)
MicroK8s 是 Canonical 官方为 Ubuntu 深度定制的轻量级单机/边缘 Kubernetes 发行版。但在国内网络或资源敏感的开发机上,常会遇到两个经典痛点:
- 网络超时导致无限卡死:直连拉取
registry.k8s.io/pause及 Calico/CoreDNS 镜像超时,节点停在NotReady状态,若执行microk8s status --wait-ready无超时限制会导致终端无限卡死。 - 后台守护进程常驻吃内存:默认情况下多项
snap.microk8s.daemon-*服务在后台常驻运行,占用数百兆到数吉内存。
1. 标准安装与初始化 (加入超时保护与别名)
# 1. 安装 microk8s
sudo snap install microk8s --classic
# 2. 配置当前用户组免 sudo 与 ~/.kube 权限
sudo usermod -a -G microk8s $USER
sudo chown -f -R $USER ~/.kube
newgrp microk8s
# 3. 配置 snap kubectl 别名 (直接使用原生 kubectl 命令)
sudo snap alias microk8s.kubectl kubectl
# 4. 放通防火墙与 CNI 网络路由 (避免 cni0 互相访问超时)
sudo ufw allow in on cni0 && sudo ufw allow out on cni0
sudo ufw default allow routed
# 5. 启动服务并带超时保护检查 (务必指定 --timeout,避免无限卡死)
microk8s start
microk8s status --wait-ready --timeout 90
# 6. 开启核心插件并导出 kubeconfig
microk8s enable dns hostpath-storage
mkdir -p ~/.kube && microk8s config > ~/.kube/config && chmod 600 ~/.kube/config
2. 网络加速与镜像拉取排坑
方案 A:为 MicroK8s containerd 配置上游代理
MicroK8s 的 containerd 运行在独立的 snap 沙盒环境中,不共用系统 Docker 代理。编辑 /var/snap/microk8s/current/args/containerd-env:
sudo bash -c 'cat << "EOF" > /var/snap/microk8s/current/args/containerd-env
HTTPS_PROXY=http://127.0.0.1:8118
HTTP_PROXY=http://127.0.0.1:8118
NO_PROXY=10.1.0.0/16,10.152.183.0/24,127.0.0.1,192.168.0.0/16,localhost
PATH=$PATH:$KATA_PATH
ulimit -n 65536 || true
ulimit -l 16384 || true
EOF'
# 重启 containerd 守护进程生效
sudo systemctl restart snap.microk8s.daemon-containerd.service
方案 B:使用透明代理 (如 vproxy) 极速拉取并导入
如果本地配置了透明代理或 CLI 代理包装工具(如 vproxy),可直接包装 microk8s.ctr 将镜像高速拉取并写入 Kubernetes 使用的 k8s.io 命名空间:
# 使用 vproxy 极速拉取 pause 基础沙盒镜像及所需应用镜像
vproxy microk8s.ctr --namespace k8s.io image pull registry.k8s.io/pause:3.10
vproxy microk8s.ctr --namespace k8s.io image pull docker.io/library/busybox:latest
3. 资源零占用:空闲时完全休眠
开发完毕后,彻底关闭后台守护进程,释放全部 CPU 和内存资源(集群配置与数据安全保留在磁盘中):
# 优雅停止集群并确保所有后台守护服务关闭
sudo microk8s stop
sudo systemctl stop $(systemctl list-unit-files 'snap.microk8s.daemon*' --no-legend 2>/dev/null | awk '{print $1}')
# 下次开工时一键秒级恢复
sudo microk8s start
microk8s status --wait-ready --timeout 60
开发者提效工具推荐
- Shell 自动补全:
# Bash echo "source <(kubectl completion bash)" >> ~/.bashrc # Zsh echo "source <(kubectl completion zsh)" >> ~/.zshrc - kubectx / kubens:快速在多个集群上下文与 Namespace 之间自由切换。
- k9s:终端全功能交互式 UI,实时查看 Pod、实时日志、Exec 终端、资源监控一应俱全。
3. Kubernetes 架构与核心组件
Kubernetes 遵循主从(Master-Worker)控制模型,采用声明式 API与**控制循环(Control Loop)**驱动系统最终状态向期望状态收敛。
控制平面 (Control Plane)
- kube-apiserver:整个集群的统一入口与数据总线,所有组件均通过 RESTful API 与其交互,负责认证、鉴权与准入控制。
- etcd:高可用的分布式键值数据库,保存集群所有的元数据与状态事实(SSOT)。
- kube-scheduler:调度器,根据节点资源利用率、污点(Taint)、亲和性(Affinity)等规则将待调度的 Pod 决策指派到合适的节点。
- kube-controller-manager:维护集群状态的核心进程(包含 NodeController、DeploymentController、EndpointSliceController 等)。
- cloud-controller-manager:集成底层公有云特定资源(负载均衡器、路由、存储卷)的控制器。
工作节点 (Worker Node)
- kubelet:运行在每个节点上的核心代理,定期向 API Server 上报节点状态,并负责驱动本地容器运行时启动、停止和健康检查容器。
- kube-proxy:负责维护节点上的网络规则(iptables / IPVS),实现 Kubernetes Service 的虚拟 IP 负载均衡与流量转发。
- Container Runtime:底层负责容器镜像拉取与生命周期管理的运行时(如 containerd)。
4. 核心资源对象与声明式模型
4.1 Pod (最小原子单位)
Pod 是 Kubernetes 中可创建和管理的最小计算单元。一个 Pod 封装了一组紧密耦合的容器(共享同一 Network Namespace、IPC 和 Storage Volumes)。
- 同 Pod 容器间通信:直接通过
localhost:port通信。 - 原生 Sidecar 模式:从 Kubernetes 1.28 起,原生支持生命周期感知型 Init/Sidecar 容器,用于日志收集、服务网格(Envoy 代理)或配置动态热重载。
4.2 工作负载控制器 (Workloads)
实际业务中很少直接创建孤立的 Pod,而是通过各类工作负载控制器进行生命周期管理:
| 控制器类型 | 核心职责 | 典型应用场景 |
|---|---|---|
| Deployment | 声明式管理无状态 Pod,支持滚动更新、弹性扩缩容、版本回退 | Web API、微服务应用 |
| StatefulSet | 管理有状态应用,保障唯一的网络身份标识(稳定主机名)、有序部署与专属持久化存储 | 数据库集群、Redis/Kafka、ZooKeeper |
| DaemonSet | 确保全部(或指定部分)节点上均运行一个 Pod 副本 | 日志收集器 (Fluentd/Filebeat)、节点监控 (Prometheus Node Exporter) |
| Job / CronJob | 一次性任务(执行完毕即退出)或基于 Cron 表达式的周期性定时任务 | 数据清洗批处理、数据库备份、定期报表统计 |
生产级 Deployment 声明示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: default
labels:
app: web-app
spec:
replicas: 3
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 0
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: server
image: nginx:1.25-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: http
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 5
4.3 服务发现与路由 (Service, Ingress & Gateway API)
Service (四层负载均衡与内部发现)
Pod 的 IP 会随着调度、漂移和销毁随时变化。Service 为一组具有相同 Label 的 Pods 提供了持久的单一入口(ClusterIP)以及集群内置 DNS 域名解析(CoreDNS)。
⚠️ 注意:
spec.ports[].protocol必须是合法的四层协议(如TCP、UDP、SCTP),不支持小写http。
apiVersion: v1
kind: Service
metadata:
name: web-app-svc
namespace: default
spec:
type: ClusterIP
selector:
app: web-app
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 80
- Service 常见类型:
ClusterIP(默认):仅集群内部可达的虚拟 IP。NodePort:在每个节点开放静态端口(默认 30000-32767),便于外部直连调试。LoadBalancer:借助云厂商或 MetalLB 自动创建外部负载均衡器。ExternalName:将服务映射到外部 DNS 域名。
Ingress 与新一代 Gateway API (七层反向代理)
- Ingress:负责管理外部 HTTP/HTTPS 流量路由至内部 Service,实现域名分流、路径重定向及 TLS 卸载。常见的 Ingress Controller 包括 Ingress-Nginx、Traefik、Envoy 等。
- Gateway API (Kubernetes 官方下一代标准):针对 Ingress 配置表现力不足、缺乏角色切分(集群管理员 vs 业务开发者)等痛点,Gateway API 提供了更加灵活、面向角色解耦与跨命名空间流量治理的全新规范。
4.4 配置与持久化存储 (ConfigMap, Secret & Storage)
- ConfigMap:以明文键值对存储应用配置,可作为环境变量注入或作为只读配置文件挂载进容器。
- Secret:用于保存敏感凭据(密码、TLS 证书、SSH 密钥),默认 Base64 编码,可结合 KMS 进行端到端加密保护。
- 持久卷 (PV & PVC):
PersistentVolume (PV):由集群管理员或存储驱动预先分配好的底层存储资源。PersistentVolumeClaim (PVC):用户/应用对存储容量和读写权限的消费申请。StorageClass:定义存储插件与动态自动供应(Dynamic Provisioning)规则。
5. 5 分钟快速实战演练
下面演示如何在本地集群完成从应用部署到排障的极简全流程:
第一步:创建资源并暴露服务
# 1. 快速创建一个包含 2 个副本的 Nginx 部署
kubectl create deployment demo-nginx --image=nginx:alpine --replicas=2
# 2. 暴露 Deployment 为 ClusterIP 服务 (指定容器端口 80)
kubectl expose deployment demo-nginx --port=8080 --target-port=80
# 3. 查看资源创建状态
kubectl get pods -l app=demo-nginx -o wide
kubectl get svc demo-nginx
第二步:本地端口转发测试
在不配置 Ingress 的情况下,可通过 kubectl port-forward 快速打通本地开发机到集群服务的网络隧道:
kubectl port-forward svc/demo-nginx 8888:8080
打开另一个终端测试连通性:
curl http://localhost:8888
第三步:日常排障核心命令 (排障四板斧)
当 Pod 状态异常(如 CrashLoopBackOff、ImagePullBackOff、Pending)时,按顺序执行以下诊断命令:
# 1. 查看 Pod 详细生命周期事件与报错(重点关注底部的 Events)
kubectl describe pod <pod-name>
# 2. 追踪查看容器控制台实时日志
kubectl logs -f <pod-name> --tail=100
# 3. 若 Pod 包含多个容器,指定容器名称查看日志
kubectl logs -f <pod-name> -c <container-name>
# 4. 直接进入容器内部调试环境
kubectl exec -it <pod-name> -- /bin/sh