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 │ └─────────────┘

图 1 \xb7 Kubernetes 架构


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 限制特权容器