Kubernetes 与云原生学习笔记
从 K8s 核心概念到集群部署实践,系统掌握容器编排与云原生生态。
1 · 容器与 K8s 概述
1.1 为什么需要容器编排
单机容器管理简单,但当你有几十上百个容器时,会面临:
- 容器该跑在哪台机器上?
- 某个容器挂了怎么自动重启?
- 流量大了怎么扩容?
- 怎么让容器互相发现?
- 怎么滚动更新不中断服务?
容器编排工具(K8s、Swarm、Nomad)就是解决这些问题。
1.2 K8s 是什么
Kubernetes,希腊语意为"舵手",简称 K8s。
核心设计哲学:声明式 API。你告诉 K8s "我想要什么状态",K8s 自动把实际状态调整成期望状态。
例如:你说"我要 3 个 nginx 副本",K8s 会确保集群里始终有 3 个 nginx 在运行。
1.3 K8s 架构
控制平面(Master):
kube-apiserver:API 入口,所有组件都通过它交互
etcd:分布式键值存储,保存集群状态
kube-scheduler:负责把 Pod 调度到合适的节点
kube-controller-manager:运行各种控制器(副本、节点、服务等)
工作节点(Worker):
kubelet:接收 API Server 指令,管理本节点容器
kube-proxy:维护网络规则,实现 Service 到 Pod 的转发
- 容器运行时:
containerd、CRI-O、Docker(1.24 后移除 dockershim)
┌──────────────┐
│ API Server │
└──────┬───────┘
┌─────────┼─────────┐
┌───┴───┐ ┌─┴─────┐ ┌────┴────┐
etcd │ │Scheduler│ │Controller│
└───┬─────┘ └─────────┘
│
┌──────┴──────┐
│ Worker │
│ kubelet │
│ kube-proxy │
│ containerd │
└─────────────┘

2 · 核心概念
2.1 Pod
Pod 是 K8s 的最小调度单位。一个 Pod 可以包含一个或多个容器,这些容器:
- 共享网络命名空间(同一个 IP)
- 共享存储卷(Volume)
- 通常一起调度到同一节点
为什么需要多容器 Pod?
例如:主应用容器 + Sidecar 日志收集容器 + Sidecar 代理容器。
2.2 Namespace
Namespace 是虚拟隔离的逻辑空间。
常见用法:
- 按环境分:
dev、staging、prod
- 按团队分:
team-a、team-b
- 按项目分
资源配额(ResourceQuota)可以按 Namespace 限制 CPU、内存、Pod 数量。
2.3 Label 和 Selector
Label 是附加到资源上的键值对,用于标识和选择。
metadata:
labels:
app: nginx
tier: frontend
Selector 通过 Label 筛选资源:
selector:
matchLabels:
app: nginx
这是 K8s 关联资源的核心机制。
3 · 工作负载
3.1 Deployment
Deployment 用于管理无状态应用,是最常用的工作负载。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
常用命令:
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl rollout status deployment/nginx
kubectl rollout undo deployment/nginx # 回滚
kubectl scale deployment nginx --replicas=5 # 扩容
3.2 StatefulSet
有状态应用使用 StatefulSet:
- Pod 有固定名称(
web-0、web-1、web-2)
- 固定网络标识(Headless Service 提供稳定 DNS)
- 稳定持久化存储(PVC 绑定到具体 Pod)
- 有序启停
适用:MySQL、MongoDB、Kafka、ZooKeeper。
3.3 DaemonSet
每个节点运行一个 Pod。
适用:
- 日志收集:Filebeat、Fluentd
- 监控 Agent:Prometheus Node Exporter
- 网络插件:Calico、Flannel
3.4 Job / CronJob
- Job:一次性任务,跑完即退出
- CronJob:定时任务
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: busybox
command: ["/bin/sh", "-c", "echo backup"]
restartPolicy: OnFailure
4 · 服务与网络
4.1 Service
Service 为一组 Pod 提供稳定的访问入口。
类型:
- ClusterIP:集群内部访问(默认)
- NodePort:暴露到节点 IP:Port
- LoadBalancer:云厂商负载均衡器
- Headless:不分配 ClusterIP,直接返回 Pod IP,用于 StatefulSet
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
4.2 Ingress
Ingress 提供七层路由,基于域名和路径转发到不同 Service。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api
port:
number: 80
常用 Ingress Controller:Nginx Ingress、Traefik、HAProxy、Istio Gateway。
4.3 K8s 网络模型
K8s 对网络的要求:
- 每个 Pod 有独立 IP
- Pod 之间可以直接通信,无需 NAT
- 节点上的 Pod 可以与所有节点上的 Pod 通信
实现方式依赖 CNI 插件:
- Flannel:简单,Overlay 网络
- Calico:支持网络策略(NetworkPolicy)
- Cilium:基于 eBPF,高性能
4.4 NetworkPolicy
NetworkPolicy 用于限制 Pod 间流量,实现微分段。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
5 · 配置与存储
5.1 ConfigMap
存储非敏感配置,可作为环境变量或文件挂载。
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.properties: |
host=mysql
port=3306
注意:修改 ConfigMap 后,已挂载的 Pod 不会自动更新,需要滚动重启。
5.2 Secret
存储敏感信息(密码、Token、证书)。
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
password: mypassword
注意:Secret 只是 Base64 编码,不是加密。生产环境建议:
- 使用 KMS 加密 etcd 中的 Secret
- 或配合 Vault、Sealed Secrets
5.3 持久化存储
PV(PersistentVolume):集群中的存储资源。
PVC(PersistentVolumeClaim):用户申请存储。
StorageClass:动态创建 PV 的模板。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
访问模式:
- ReadWriteOnce(RWO):单节点读写
- ReadOnlyMany(ROX):多节点只读
- ReadWriteMany(RWX):多节点读写
- ReadWriteOncePod(RWOP):单 Pod 读写
6 · Helm 包管理
6.1 概念
Helm 是 K8s 的包管理器。
- Chart:一个 K8s 应用包,包含模板和默认值
- Release:Chart 的一次安装实例
- Values:用户自定义配置
6.2 常用命令
# 添加仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# 安装
helm install my-mysql bitnami/mysql
# 查看 release
helm list
# 升级
helm upgrade my-mysql bitnami/mysql -f values.yaml
# 回滚
helm rollback my-mysql 1
# 卸载
helm uninstall my-mysql
6.3 自定义 Chart
mychart/
├── Chart.yaml # Chart 元数据
├── values.yaml # 默认值
├── templates/ # K8s 资源模板
│ ├── deployment.yaml
│ ├── service.yaml
│ └── _helpers.tpl
└── charts/ # 依赖的子 Chart
templates 使用 Go Template 语法:
replicas: {{ .Values.replicaCount }}
7 · 集群部署实践
7.1 kubeadm 部署
Master 节点:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
安装网络插件(Flannel):
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
Worker 节点加入:
sudo kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
7.2 常用排查命令
kubectl get nodes -o wide
kubectl get pods -A
kubectl describe pod <pod-name>
kubectl logs <pod-name> -f
kubectl exec -it <pod-name> -- /bin/sh
kubectl get events --sort-by=.lastTimestamp
kubectl top node
kubectl top pod
7.3 生产环境 checklist
- 控制面高可用:3 Master + etcd 集群
- 节点自动扩缩容:Cluster Autoscaler
- 资源限制:requests/limits 必须设置
- 健康检查:livenessProbe / readinessProbe / startupProbe
- 日志收集:Fluentd + Elasticsearch + Kibana 或 Loki
- 监控告警:Prometheus + Grafana
- 备份 etcd:定期快照
- NetworkPolicy 限制 Pod 间流量
- PodSecurity 或 OPA Gatekeeper 限制特权容器