Kubernetes (K8s)

技术栈
工具链
容器编排K8s云原生微服务调度

概览

Kubernetes (K8s)

Kubernetes 是 Google 基于 Borg 经验开源的容器编排平台,现由 CNCF 托管。它是云原生生态的核心,用于自动化部署、扩展和管理容器化应用。

核心价值:声明式配置驱动的集群管理,自动调度、自愈、滚动更新、水平伸缩。从单机到万级节点统一管理。

关键特性

  • Pod 模型(最小调度单元,共享网络/存储)
  • Service 发现与负载均衡
  • 自动装箱(Scheduling)+ 自动扩缩容(HPA/VPA)
  • 声明式配置(YAML/JSON)+ 控制器模式
  • 滚动更新与回滚,零停机部署
  • 持久化存储编排(CSI)

安装

1. 环境准备

  • 操作系统:Linux(生产)、macOS、Windows(WSL2)
  • 容器运行时:containerd(推荐)、CRI-O、Docker Engine(已弃用)
  • 内存:Master 节点 2GB+,Worker 节点 1GB+
  • 网络:所有节点间互通,需安装 CNI 插件

2. 安装命令

本地开发 — kind 快速体验

# 安装 kind
brew install kind  # macOS
# 或 go install sigs.k8s.io/kind@latest

# 创建单节点集群
kind create cluster --name dev

# 验证
kubectl cluster-info
kubectl get nodes

本地开发 — minikube

brew install minikube  # macOS
minikube start --driver=docker
minikube dashboard

生产集群 — kubeadm(Ubuntu)

# 1. 在所有节点上安装 kubeadm、kubelet、kubectl
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

# 2. 初始化 Master 节点
sudo kubeadm init --pod-network-cidr=10.244.0.0/16

# 3. 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 4. 安装 CNI 网络插件(Flannel)
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

# 5. Worker 节点加入(使用 init 输出的命令)
sudo kubeadm join <;master-ip>:6443 --token <token> --discovery-token-ca-cert-hash <hash>

托管服务

  • AWS EKSeksctl create cluster --name my-cluster --region us-east-1
  • GCP GKEgcloud container clusters create my-cluster
  • Azure AKSaz aks create --resource-group myRG --name myCluster

3. 常见安装问题

问题 解决方案
kubelet 无法启动 检查容器运行时(containerd)是否运行:systemctl status containerd
Node 状态 NotReady CNI 插件未安装或配置错误,kubectl describe node 查看事件
kubectl 连接被拒 ~/.kube/config 不存在或 IP 不对,重新 cp admin.conf
kubeadm init 失败 SWAP 未关闭:sudo swapoff -a,并注释 /etc/fstab 中 swap 行
镜像拉取失败 (ImagePullBackOff) 配置镜像加速或 Docker Hub 代理

示例

K8s 部署完整 Web 应用

目标

部署一个 Flask Web 应用,包含 Deployment、Service、ConfigMap、Ingress。

完整 YAML

1. ConfigMap(configmap.yaml)

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  ENV: "production"
  LOG_LEVEL: "info"

2. Deployment(deployment.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: flask-app
  labels:
    app: flask-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: flask-app
  template:
    metadata:
      labels:
        app: flask-app
    spec:
      containers:
      - name: flask
        image: myregistry/flask-app:v1.0
        ports:
        - containerPort: 5000
        envFrom:
        - configMapRef:
            name: app-config
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 256Mi
        livenessProbe:
          httpGet:
            path: /health
            port: 5000
          initialDelaySeconds: 5
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 5000
          initialDelaySeconds: 3
          periodSeconds: 5

3. Service(service.yaml)

apiVersion: v1
kind: Service
metadata:
  name: flask-svc
spec:
  type: ClusterIP
  selector:
    app: flask-app
  ports:
  - port: 80
    targetPort: 5000
    protocol: TCP

4. Ingress(ingress.yaml)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: flask-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: flask-svc
            port:
              number: 80

运行步骤

# 1. 应用所有资源
kubectl apply -f configmap.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

# 2. 查看状态
kubectl get pods -w                    # 等待 Pod Ready
kubectl get svc flask-svc             # 查看 Service
kubectl get ingress flask-ingress     # 查看 Ingress

# 3. 端口转发测试(本地没有 Ingress Controller 时)
kubectl port-forward svc/flask-svc 8080:80
curl http://localhost:8080/

# 4. 扩容
kubectl scale deployment flask-app --replicas=5

# 5. 滚动更新
kubectl set image deployment/flask-app flask=myregistry/flask-app:v2.0
kubectl rollout status deployment/flask-app

# 6. 回滚
kubectl rollout undo deployment/flask-app

预期输出

Pod 全部 Ready 后,curl 应返回:

Hello from flask-app-<pod-hash> | ENV=production

教程

Kubernetes 入门教程:核心对象与调度原理

1. 为什么需要 K8s?

Docker 解决单机容器问题,但生产环境有几十上百台机器:

  • 容器放哪台机器?(调度)
  • 机器挂了容器怎么办?(自愈)
  • 流量大了怎么扩容?(自动伸缩)
  • 服务之间怎么发现?(网络)
  • 配置怎么管理?(配置中心)

Kubernetes 统一解决上述问题,将数据中心视为一台计算机。

2. 核心对象图谱

Cluster
├── Namespace (逻辑隔离)
│   ├── Pod (最小调度单元,1+ 容器共享网络)
│   │   ├── Container
│   │   └── Volume
│   ├── Deployment (管理 Pod 副本,滚动更新)
│   ├── ReplicaSet (维护固定数量 Pod)
│   ├── Service (Pod 网络抽象,稳定 IP/DNS)
│   ├── ConfigMap / Secret (配置解耦)
│   └── Ingress (七层路由,域名 → Service)
├── PersistentVolume / PersistentVolumeClaim
└── Node (物理/虚拟机)

3. Pod 详解

Pod 是 K8s 最小调度单元,一个 Pod 内所有容器共享网络 namespace 和 IPC

spec:
  containers:
  - name: app
    image: myapp:latest
    ports: [containerPort: 5000]
  - name: sidecar  # 日志收集 sidecar
    image: fluentd:latest
    volumeMounts:
    - name: logs
      mountPath: /var/log/app

Pod 生命周期

Pending → Running → Succeeded (正常退出)
                   → Failed (异常退出)
     → Unknown

探针类型

探针 作用 失败后果
livenessProbe 容器是否存活 重启容器
readinessProbe 是否可接受流量 从 Service Endpoint 移除
startupProbe 启动是否完成 阻塞其他探针

4. Service 类型

类型 访问范围 使用场景
ClusterIP 集群内部 后端服务间通信
NodePort 节点 IP + 端口 开发调试
LoadBalancer 外部 LB 生产对外暴露
ExternalName DNS CNAME 外部服务映射

5. 调度机制

K8s 调度器通过 Filtering(过滤)→ Scoring(打分) 选择最优 Node:

# 节点亲和性
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: disktype
          operator: In
          values: [ssd]

# Pod 反亲和性(分散部署)
podAntiAffinity:
  preferredDuringSchedulingIgnoredDuringExecution:
  - weight: 100
    podAffinityTerm:
      topologyKey: kubernetes.io/hostname

6. 思考题

  1. Deployment 和 StatefulSet 的核心区别?什么场景用 StatefulSet?
  2. Service 如何实现 Pod 发现?kube-proxy 的 iptables 和 IPVS 模式有何不同?
  3. 为什么建议一个 Pod 只跑一个容器?Sidecar 模式的例外场景有哪些?

参考资料

暂无参考文献