跳转至

第03章 Kubernetes核心

Kubernetes核心图

📚 章节概述

本章将深入讲解Kubernetes(K8s)的核心概念、架构设计、Pod管理、Service服务发现、Deployment部署等核心功能。通过本章学习,你将能够熟练使用Kubernetes进行容器编排,为生产环境部署打下坚实基础。

🎯 学习目标

完成本章后,你将能够:

  1. 理解Kubernetes的架构和核心组件
  2. 掌握Pod的生命周期和管理
  3. 熟练使用Service进行服务发现
  4. 掌握Deployment的部署和更新策略
  5. 理解Kubernetes的网络模型
  6. 能够编写Kubernetes YAML配置文件
  7. 掌握kubectl命令行工具的使用

3.1 Kubernetes概述

3.1.1 什么是Kubernetes

Kubernetes(简称K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用。它最初由Google设计,现在由CNCF(云原生计算基金会)维护。

Kubernetes的核心价值

  1. 自动化运维
  2. 自动部署和回滚
  3. 自动扩缩容
  4. 自动故障恢复
  5. 自动负载均衡

  6. 服务发现和负载均衡

  7. 内置服务发现机制
  8. 自动负载均衡
  9. 支持多种负载均衡策略

  10. 存储编排

  11. 自动挂载存储卷
  12. 支持多种存储后端
  13. 存储动态供应

  14. 自我修复

  15. 自动重启失败的容器
  16. 自动替换不健康的节点
  17. 自动杀死不响应的容器

  18. 密钥和配置管理

  19. 集中管理配置
  20. 密钥安全存储
  21. 配置热更新

3.1.2 Kubernetes架构

Kubernetes采用主从(Master-Node)架构,主要组件包括:

控制平面(Control Plane)

Text Only
┌─────────────────────────────────────────────────────────┐
│                    控制平面 (Control Plane)              │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │   API Server │  │   Scheduler  │  │ Controller   │  │
│  │              │  │              │  │   Manager    │  │
│  │  RESTful API │  │  调度Pod到   │  │  维护集群    │  │
│  │  统一入口    │  │  合适的节点  │  │  期望状态    │  │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘  │
│         │                  │                  │          │
│         └──────────────────┼──────────────────┘          │
│                            │                             │
│                   ┌────────▼────────┐                    │
│                   │   etcd         │                    │
│                   │   键值存储      │                    │
│                   │   存储集群状态  │                    │
│                   └─────────────────┘                    │
│                                                          │
└─────────────────────────────────────────────────────────┘

核心组件详解

  1. API Server
  2. Kubernetes API的统一入口
  3. 处理REST操作
  4. 验证和配置数据
  5. 提供认证、授权、准入控制

  6. etcd

  7. 高可用的键值存储
  8. 存储集群所有配置和状态
  9. 提供分布式锁和选举
  10. 数据一致性保证

  11. Scheduler

  12. 调度Pod到合适的节点
  13. 考虑资源需求、策略约束
  14. 优化资源利用率
  15. 支持多种调度算法

  16. Controller Manager

  17. 运行多种控制器
  18. 维护集群期望状态
  19. 处理节点故障
  20. 执行滚动更新

工作节点(Worker Node)

Text Only
┌─────────────────────────────────────────────────────────┐
│                    工作节点 (Worker Node)               │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │   Kubelet    │  │  Kube-Proxy  │  │ Container    │  │
│  │              │  │              │  │ Runtime      │  │
│  │  管理Pod     │  │  网络代理     │  │  Docker/     │  │
│  │  与API通信   │  │  服务发现     │  │  containerd  │  │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘  │
│         │                  │                  │          │
│         └──────────────────┼──────────────────┘          │
│                            │                             │
│                   ┌────────▼────────┐                    │
│                   │   Pods         │                    │
│                   │  容器组         │                    │
│                   │  共享网络/存储  │                    │
│                   └─────────────────┘                    │
│                                                          │
└─────────────────────────────────────────────────────────┘

节点组件详解

  1. Kubelet
  2. 与API Server通信
  3. 管理Pod生命周期
  4. 汇报节点状态
  5. 执行健康检查

  6. Kube-proxy

  7. 维护网络规则
  8. 实现Service负载均衡
  9. 支持多种代理模式
  10. 处理网络策略

  11. Container Runtime

  12. 运行容器
  13. 拉取镜像
  14. 管理容器生命周期
  15. 支持CRI接口

3.1.3 Kubernetes工作流程

Text Only
用户提交YAML配置
  API Server
   etcd存储
  Controller Manager
  (检测期望状态)
   Scheduler
  (调度Pod到节点)
   Kubelet
  (在节点上创建Pod)
  Container Runtime
  (启动容器)
   运行状态
  Controller Manager
  (监控并维护状态)

3.2 安装Kubernetes

3.2.1 使用Minikube(本地开发)

Bash
# 安装Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# 启动Minikube
minikube start --driver=docker

# 查看状态
minikube status

# 查看集群信息
kubectl cluster-info

# 查看节点
kubectl get nodes

# 停止Minikube
minikube stop

# 删除Minikube
minikube delete

3.2.2 使用kubeadm(生产环境)

Master节点安装

Bash
# 1. 安装依赖
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

# 2. 添加Kubernetes仓库(请根据当前最新稳定版更新版本号)
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/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.32/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

# 3. 安装Kubernetes组件
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

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

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

# 6. 安装网络插件(以Calico为例)
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.1/manifests/calico.yaml

# 7. 查看节点状态
kubectl get nodes

Worker节点加入

Bash
# 1. 安装Kubernetes组件(同Master节点)
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

# 2. 加入集群(使用kubeadm init输出的join命令)
sudo kubeadm join <master-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

3.2.3 使用云平台(推荐)

AWS EKS

Bash
# 安装eksctl
curl --location "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin

# 创建集群
eksctl create cluster \
  --name my-cluster \
  --region us-west-2 \
  --nodes 3 \
  --node-type t3.medium \
  --managed

# 获取凭证
aws eks update-kubeconfig --region us-west-2 --name my-cluster

# 查看节点
kubectl get nodes

阿里云ACK

Bash
# 安装kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"  # $()命令替换:执行命令并获取输出
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# 获取集群凭证
aliyun cs GET /k8s/<cluster-id>/user_config | kubectl config use-context <context>  # |管道:将前一命令的输出作为后一命令的输入

# 查看节点
kubectl get nodes

3.3 Pod核心概念

3.3.1 什么是Pod

Pod是Kubernetes中最小的可部署单元,包含一个或多个容器,这些容器共享网络和存储。

Pod的特点

  1. 共享网络
  2. 同一Pod内的容器共享网络命名空间
  3. 容器间可以通过localhost通信
  4. 共享端口空间

  5. 共享存储

  6. 可以挂载共享的Volume
  7. 容器间共享数据

  8. 原子性

  9. Pod作为一个整体被调度
  10. 同一Pod的容器总是在同一节点

  11. 临时性

  12. Pod是临时的、可替换的
  13. IP地址会变化
  14. 不保证持久存储

3.3.2 Pod生命周期

Text Only
Pending → Running → Succeeded/Failed
    Unknown

Pod状态说明

  1. Pending
  2. Pod已创建,但容器还未启动
  3. 正在下载镜像或调度中

  4. Running

  5. Pod已绑定到节点
  6. 所有容器都已创建
  7. 至少有一个容器正在运行

  8. Succeeded

  9. Pod中的所有容器都已成功终止
  10. 不会重启

  11. Failed

  12. Pod中的所有容器都已终止
  13. 至少有一个容器以失败状态终止

  14. Unknown

  15. 无法获取Pod状态
  16. 通常是由于通信问题

3.3.3 创建Pod

基本Pod配置

YAML
apiVersion: v1              # API版本
kind: Pod                   # 资源类型:Pod(最小调度单元)
metadata:
  name: nginx-pod           # Pod名称,集群内唯一标识
  labels:                   # 标签,用于Service选择器和分组管理
    app: nginx
    env: production
spec:
  containers:
  - name: nginx             # 容器名称
    image: nginx:1.27       # 使用的镜像及版本标签
    ports:
    - containerPort: 80     # 容器监听端口
    resources:
      requests:             # 最小资源请求(调度器依据此值分配节点)
        memory: "64Mi"      # 最少需要64MB内存
        cpu: "250m"         # 最少需要0.25核CPU
      limits:               # 资源上限(超出内存会OOM终止,超出CPU会被限流)
        memory: "128Mi"
        cpu: "500m"
    livenessProbe:          # 存活探针:探测失败时自动重启容器
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 30  # 容器启动后等待30秒再开始探测
      periodSeconds: 10        # 每隔10秒探测一次
    readinessProbe:         # 就绪探针:探测失败时从Service端点中移除
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5   # 启动后5秒开始探测
      periodSeconds: 5         # 每隔5秒探测一次

多容器Pod

YAML
apiVersion: v1
kind: Pod
metadata:
  name: multi-container-pod    # 多容器Pod示例(Sidecar模式)
spec:
  containers:
  - name: nginx                # 主容器:Nginx Web服务器
    image: nginx:1.27
    ports:
    - containerPort: 80
    volumeMounts:
    - name: shared-data        # 挂载共享卷,读取sidecar生成的内容
      mountPath: /usr/share/nginx/html

  - name: content-generator    # Sidecar容器:辅助内容生成器
    image: busybox
    command: ["/bin/sh", "-c"]
    args:
      - while true; do
          echo "$(date) - Hello from sidecar" >> /data/index.html;
          sleep 10;
        done
    volumeMounts:
    - name: shared-data        # 挂载同一共享卷,写入生成的内容
      mountPath: /data

  volumes:
  - name: shared-data          # 共享卷定义
    emptyDir: {}               # emptyDir:Pod生命周期内的临时存储

创建和查看Pod

Bash
# 创建Pod
kubectl apply -f pod.yaml

# 查看Pod
kubectl get pods
kubectl get pods -o wide
kubectl get pods -l app=nginx

# 查看Pod详情
kubectl describe pod nginx-pod

# 查看Pod日志
kubectl logs nginx-pod
kubectl logs nginx-pod -c content-generator  # 查看特定容器日志
kubectl logs nginx-pod -f  # 跟踪日志

# 进入Pod
kubectl exec -it nginx-pod -- /bin/bash

# 删除Pod
kubectl delete pod nginx-pod
kubectl delete pod -l app=nginx

3.3.4 Pod资源管理

资源请求和限制

YAML
apiVersion: v1
kind: Pod
metadata:
  name: resource-pod
spec:
  containers:
  - name: app
    image: nginx:1.27
    resources:
      requests:              # 资源请求:调度器保证节点至少有这么多可用资源
        memory: "256Mi"      # 内存请求256MB
        cpu: "500m"          # CPU请求0.5核
      limits:                # 资源限制:容器使用资源的硬上限
        memory: "512Mi"      # 内存上限512MB(超出触发OOM Kill)
        cpu: "1000m"         # CPU上限1核(超出会被节流)

资源说明

  • requests:Pod运行所需的最小资源
  • 调度器根据requests选择节点
  • 保证Pod至少获得这些资源

  • limits:Pod可使用的最大资源

  • 防止Pod占用过多资源
  • 超过限制会被限制或终止

3.3.5 健康检查

Liveness Probe(存活探针)

YAML
apiVersion: v1
kind: Pod
metadata:
  name: liveness-pod
spec:
  containers:
  - name: app
    image: nginx:1.27
    livenessProbe:             # 存活探针:检测容器是否正常运行
      httpGet:                 # HTTP探测方式(还支持exec和tcpSocket)
        path: /health          # 探测路径
        port: 80               # 探测端口
      initialDelaySeconds: 30  # 容器启动后等待30秒再探测
      periodSeconds: 10        # 每10秒探测一次
      timeoutSeconds: 5        # 探测超时时间5秒
      failureThreshold: 3     # 连续失败3次则重启容器

Readiness Probe(就绪探针)

YAML
apiVersion: v1
kind: Pod
metadata:
  name: readiness-pod
spec:
  containers:
  - name: app
    image: nginx:1.27
    readinessProbe:            # 就绪探针:检测容器是否准备好接收流量
      httpGet:
        path: /ready           # 就绪检查路径
        port: 80
      initialDelaySeconds: 5   # 启动后5秒开始探测
      periodSeconds: 5         # 每5秒探测一次
      timeoutSeconds: 3        # 探测超时3秒
      failureThreshold: 3     # 连续失败3次则标记为未就绪,从Service端点移除

Startup Probe(启动探针)

YAML
apiVersion: v1
kind: Pod
metadata:
  name: startup-pod
spec:
  containers:
  - name: app
    image: nginx:1.27
    startupProbe:              # 启动探针:保护慢启动容器,启动完成前不执行其他探针
      httpGet:
        path: /startup
        port: 80
      initialDelaySeconds: 0   # 立即开始探测
      periodSeconds: 5         # 每5秒探测一次
      timeoutSeconds: 3        # 超时3秒
      failureThreshold: 30    # 最多允许失败30次(即最长等待150秒启动)

3.4 Service服务发现

3.4.1 什么是Service

Service定义了一组Pod的访问策略,提供稳定的网络端点,实现服务发现和负载均衡。

Service的类型

  1. ClusterIP(默认)
  2. 集群内部可访问
  3. 分配集群内部IP
  4. 适用于内部服务

  5. NodePort

  6. 通过节点IP和端口访问
  7. 每个节点开放相同端口
  8. 适用于开发测试

  9. LoadBalancer

  10. 通过云服务商的负载均衡器访问
  11. 分配外部IP
  12. 适用于生产环境

  13. ExternalName

  14. 映射到外部DNS名称
  15. 不创建代理
  16. 适用于外部服务

3.4.2 创建Service

ClusterIP Service

YAML
apiVersion: v1
kind: Service
metadata:
  name: nginx-service          # Service名称(同时作为集群内DNS名)
spec:
  selector:                    # 标签选择器:匹配对应的Pod
    app: nginx
  ports:
  - protocol: TCP
    port: 80                   # Service暴露的端口
    targetPort: 80             # 转发到Pod的目标端口
  type: ClusterIP              # 类型:仅集群内部可访问(默认类型)

NodePort Service

YAML
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80                   # Service端口
    targetPort: 80             # Pod目标端口
    nodePort: 30080            # 节点端口(范围30000-32767),可通过节点IP:30080访问
  type: NodePort               # 类型:通过每个节点的IP和静态端口暴露服务

LoadBalancer Service

YAML
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80                   # 负载均衡器监听端口
    targetPort: 80             # 转发到Pod的端口
  type: LoadBalancer           # 类型:通过云厂商负载均衡器暴露,自动分配外部IP

3.4.3 Service操作

Bash
# 创建Service
kubectl apply -f service.yaml

# 查看Service
kubectl get services
kubectl get svc

# 查看Service详情
kubectl describe service nginx-service

# 查看Service端点
kubectl get endpoints nginx-service

# 测试Service访问
kubectl run test --image=busybox --rm -it -- wget -O- http://nginx-service

# 删除Service
kubectl delete service nginx-service

3.4.4 Headless Service

YAML
apiVersion: v1
kind: Service
metadata:
  name: headless-service       # Headless Service:无集群IP的特殊Service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  clusterIP: None              # 设为None表示Headless Service,DNS直接返回Pod IP列表

Headless Service的特点: - 不分配ClusterIP - DNS返回所有Pod的IP - 用于StatefulSet等场景

3.5 Deployment部署管理

3.5.1 什么是Deployment

Deployment用于管理Pod和ReplicaSet,提供声明式的更新方式,支持滚动更新和回滚。

Deployment的功能

  1. Pod副本管理
  2. 维护指定数量的Pod副本
  3. 自动替换失败的Pod
  4. 支持水平扩展

  5. 滚动更新

  6. 逐步替换旧版本Pod
  7. 零停机更新
  8. 可控制更新策略

  9. 回滚

  10. 快速回滚到之前版本
  11. 保留历史版本
  12. 支持版本对比

  13. 暂停和恢复

  14. 暂停更新过程
  15. 恢复更新
  16. 调试更新问题

3.5.2 创建Deployment

基本Deployment

YAML
apiVersion: apps/v1            # apps组的v1版本API
kind: Deployment               # 资源类型:Deployment(声明式部署管理)
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3                  # 期望副本数:维持3个Pod实例
  selector:
    matchLabels:               # 选择器:匹配template中定义的Pod标签
      app: nginx
  template:                    # Pod模板:定义要创建的Pod规格
    metadata:
      labels:
        app: nginx
    spec:
      securityContext:         # Pod级别安全上下文
        runAsNonRoot: true     # 禁止以root用户运行
        seccompProfile:
          type: RuntimeDefault # 使用默认的系统调用过滤配置
      containers:
      - name: nginx
        image: nginx:1.27
        ports:
        - containerPort: 80
        resources:
          requests:            # 最小资源请求
            memory: "64Mi"
            cpu: "250m"
          limits:              # 最大资源限制
            memory: "128Mi"
            cpu: "500m"
        securityContext:       # 容器级别安全策略
          allowPrivilegeEscalation: false  # 禁止提权
          readOnlyRootFilesystem: true     # 根文件系统只读
          capabilities:
            drop: ["ALL"]      # 丢弃所有Linux能力,最小权限原则
        livenessProbe:         # 存活探针
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:        # 就绪探针
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5

创建和查看Deployment

Bash
# 创建Deployment
kubectl apply -f deployment.yaml

# 查看Deployment
kubectl get deployments
kubectl get deploy

# 查看Deployment详情
kubectl describe deployment nginx-deployment

# 查看Pod
kubectl get pods -l app=nginx

# 查看ReplicaSet
kubectl get replicasets
kubectl get rs

3.5.3 扩缩容

手动扩缩容

Bash
# 扩展到5个副本
kubectl scale deployment nginx-deployment --replicas=5

# 缩减到2个副本
kubectl scale deployment nginx-deployment --replicas=2

# 查看扩缩容状态
kubectl get pods -l app=nginx

自动扩缩容(HPA)

YAML
apiVersion: autoscaling/v2        # 使用v2版本支持多指标
kind: HorizontalPodAutoscaler     # 水平Pod自动扩缩容器
metadata:
  name: nginx-hpa
spec:
  scaleTargetRef:                  # 扩缩目标:关联的Deployment
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-deployment
  minReplicas: 2                   # 最小副本数
  maxReplicas: 10                  # 最大副本数
  metrics:                         # 扩缩指标(支持多指标联合决策)
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50     # CPU平均使用率超过50%时扩容
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80     # 内存平均使用率超过80%时扩容
Bash
# 创建HPA
kubectl apply -f hpa.yaml

# 查看HPA
kubectl get hpa

# 查看HPA详情
kubectl describe hpa nginx-hpa

3.5.4 滚动更新

更新镜像版本

Bash
# 更新镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.27

# 或使用edit命令
kubectl edit deployment nginx-deployment

# 查看更新状态
kubectl rollout status deployment/nginx-deployment

# 查看更新历史
kubectl rollout history deployment/nginx-deployment

# 查看特定版本详情
kubectl rollout history deployment/nginx-deployment --revision=2

更新策略配置

YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 更新期间最多可以比期望值多出的Pod数量
      maxUnavailable: 1  # 更新期间最多可以有多少个Pod不可用
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.27
        ports:
        - containerPort: 80

3.5.5 回滚

回滚到之前版本

Bash
# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment

# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2

# 查看回滚状态
kubectl rollout status deployment/nginx-deployment

暂停和恢复

Bash
# 暂停Deployment
kubectl rollout pause deployment/nginx-deployment

# 恢复Deployment
kubectl rollout resume deployment/nginx-deployment

3.6 完整实战项目

3.6.1 项目概述

部署一个完整的Web应用,包括: - Nginx前端 - Flask后端API - MySQL数据库 - Redis缓存 - 监控和日志

3.6.2 项目结构

Text Only
k8s-project/
├── namespace.yaml
├── configmap.yaml
├── secret.yaml
├── mysql/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── pvc.yaml
├── redis/
│   ├── deployment.yaml
│   └── service.yaml
├── backend/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── hpa.yaml
├── frontend/
│   ├── deployment.yaml
│   └── service.yaml
└── monitoring/
    ├── prometheus/
    └── grafana/

3.6.3 Namespace配置

YAML
apiVersion: v1
kind: Namespace                # 命名空间:用于资源隔离和多租户管理
metadata:
  name: webapp                 # 命名空间名称
  labels:
    name: webapp
    environment: production    # 标识生产环境,便于按环境筛选

3.6.4 ConfigMap配置

YAML
apiVersion: v1
kind: ConfigMap                # ConfigMap:存储非敏感配置数据
metadata:
  name: app-config
  namespace: webapp            # 所属命名空间
data:                          # 键值对形式的配置数据(可被Pod以环境变量或卷方式引用)
  database_host: "mysql-service"   # 数据库主机(使用Service名称实现服务发现)
  database_port: "3306"
  database_name: "appdb"
  redis_host: "redis-service"      # Redis主机
  redis_port: "6379"
  app_env: "production"            # 应用运行环境
  log_level: "info"                # 日志级别

3.6.5 Secret配置

YAML
# ⚠️ 安全警告:以下配置包含硬编码密码,仅用于演示目的。
# 在生产环境中,请务必使用环境变量或密钥管理服务来存储敏感信息。
apiVersion: v1
kind: Secret                   # Secret:存储敏感数据(密码、令牌、密钥等)
metadata:
  name: app-secret
  namespace: webapp
type: Opaque                   # 类型:Opaque为通用密钥类型
data:                          # data中的值必须是base64编码(echo -n 'value' | base64)
  database_password: cm9vdHBhc3N3b3Jk  # base64编码的数据库密码
  redis_password: cmVkaXNwYXNzd29yZA==  # base64编码的Redis密码
  jwt_secret: and0LXNlY3JldC1rZXk=     # base64编码的JWT密钥

3.6.6 MySQL部署

YAML
# mysql/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: webapp
spec:
  replicas: 1                  # 数据库通常单副本(主从需要StatefulSet)
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.4
        ports:
        - containerPort: 3306  # MySQL默认端口
        env:                   # 环境变量配置(从Secret中引用敏感信息)
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:      # 从Secret对象中读取密码
              name: app-secret
              key: database_password
        - name: MYSQL_DATABASE
          value: appdb         # 自动创建的初始数据库
        - name: MYSQL_USER
          value: appuser       # 创建的普通用户
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: database_password
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql  # MySQL数据目录挂载持久卷
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"
        livenessProbe:         # 存活探针:通过mysqladmin ping检测
          exec:
            command: ["mysqladmin", "ping", "-h", "localhost"]
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:        # 就绪探针:通过执行SQL语句检测
          exec:
            command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
          initialDelaySeconds: 5
          periodSeconds: 5
      volumes:
      - name: mysql-data
        persistentVolumeClaim:
          claimName: mysql-pvc # 引用持久卷声明,确保数据持久化
YAML
# mysql/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql-service          # Service名即集群内DNS名(mysql-service.webapp.svc)
  namespace: webapp
spec:
  selector:
    app: mysql                 # 匹配MySQL Pod
  ports:
  - protocol: TCP
    port: 3306                 # Service暴露端口
    targetPort: 3306           # 转发到Pod的3306端口
  type: ClusterIP              # 数据库仅集群内部访问,不对外暴露
YAML
# mysql/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim    # 持久卷声明:申请存储资源
metadata:
  name: mysql-pvc
  namespace: webapp
spec:
  accessModes:
    - ReadWriteOnce            # 访问模式:单节点读写(适合数据库)
  resources:
    requests:
      storage: 10Gi            # 申请10GB存储空间
  storageClassName: standard   # 存储类名称(由集群管理员预先配置)

3.6.7 Redis部署

YAML
# redis/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: webapp
spec:
  replicas: 1                  # Redis单实例(高可用可使用Sentinel或Cluster模式)
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:7.2-alpine    # Alpine镜像更轻量
        command: ["redis-server", "--requirepass", "$(REDIS_PASSWORD)", "--appendonly", "yes"]
        # 启用密码认证和AOF持久化
        ports:
        - containerPort: 6379      # Redis默认端口
        env:
        - name: REDIS_PASSWORD     # 从Secret获取密码
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: redis_password
        volumeMounts:
        - name: redis-data
          mountPath: /data         # Redis数据目录
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"
        livenessProbe:             # 存活探针
          exec:
            command: ["redis-cli", "--raw", "incr", "ping"]
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:            # 就绪探针
          exec:
            command: ["redis-cli", "ping"]
          initialDelaySeconds: 5
          periodSeconds: 5
      volumes:
      - name: redis-data
        emptyDir: {}               # 临时存储(生产环境建议使用PVC)
YAML
# redis/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis-service          # 集群内通过redis-service访问Redis
  namespace: webapp
spec:
  selector:
    app: redis
  ports:
  - protocol: TCP
    port: 6379                 # Redis服务端口
    targetPort: 6379
  type: ClusterIP              # 仅集群内部访问

3.6.8 Backend部署

YAML
# backend/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  namespace: webapp
spec:
  replicas: 3                  # 后端API运行3个副本实现负载均衡
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      securityContext:         # Pod安全策略
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: backend
        image: myregistry.com/backend:v1.0  # 私有镜像仓库
        ports:
        - containerPort: 8000  # 后端API端口
        securityContext:       # 容器安全策略:最小权限
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
        env:                   # 环境变量:从ConfigMap和Secret注入配置
        - name: DATABASE_HOST          # 数据库配置(从ConfigMap读取)
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: database_host
        - name: DATABASE_PORT
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: database_port
        - name: DATABASE_NAME
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: database_name
        - name: DATABASE_PASSWORD      # 敏感信息(从Secret读取)
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: database_password
        - name: REDIS_HOST             # Redis配置
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: redis_host
        - name: REDIS_PORT
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: redis_port
        - name: REDIS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: redis_password
        - name: APP_ENV                # 应用环境与日志配置
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: app_env
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: log_level
        resources:             # 资源管理
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:         # 存活探针
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:        # 就绪探针
          httpGet:
            path: /ready
            port: 8000
          initialDelaySeconds: 5
          periodSeconds: 5
YAML
# backend/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: backend-service        # 后端API的Service(内部服务,供前端调用)
  namespace: webapp
spec:
  selector:
    app: backend               # 匹配后端Pod
  ports:
  - protocol: TCP
    port: 80                   # Service端口(对外暴青80端口)
    targetPort: 8000           # 转发到Pod的8000端口
  type: ClusterIP              # 仅集群内部访问
YAML
# backend/hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler     # 后端API自动扩缩容
metadata:
  name: backend-hpa
  namespace: webapp
spec:
  scaleTargetRef:                  # 扩缩目标
    apiVersion: apps/v1
    kind: Deployment
    name: backend
  minReplicas: 3                   # 最少3个副本保障可用性
  maxReplicas: 10                  # 最多扩展到10个副本
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70     # CPU使用率>70%触发扩容
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80     # 内存使用率>80%触发扩容

3.6.9 Frontend部署

YAML
# frontend/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  namespace: webapp
spec:
  replicas: 2                  # 前端2个副本(静态资源负载较低)
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      securityContext:         # Pod安全上下文
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: frontend
        image: myregistry.com/frontend:v1.0  # 前端静态资源镜像
        ports:
        - containerPort: 80    # Nginx默认端口
        securityContext:       # 容器安全策略
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true  # 根文件系统只读
          capabilities:
            drop: ["ALL"]
        resources:             # 前端资源需求较低
          requests:
            memory: "64Mi"
            cpu: "100m"
          limits:
            memory: "128Mi"
            cpu: "200m"
        livenessProbe:         # 存活探针
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:        # 就绪探针
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
YAML
# frontend/service.yaml
apiVersion: v1  # apiVersion指定K8s API版本
kind: Service  # kind指定资源类型
metadata:
  name: frontend-service       # 前端Service(对外暴露)
  namespace: webapp
spec:  # spec定义资源的期望状态
  selector:
    app: frontend
  ports:
  - protocol: TCP
    port: 80                   # 外部访问端口
    targetPort: 80             # 转发到前端Pod的80端口
  type: LoadBalancer           # 通过云厂商负载均衡器对外暴露,用户直接访问

3.6.10 部署脚本

Bash
#!/bin/bash

# 部署脚本

set -e

echo "开始部署应用..."

# 1. 创建Namespace
echo "创建Namespace..."
kubectl apply -f namespace.yaml

# 2. 创建ConfigMap和Secret
echo "创建ConfigMap和Secret..."
kubectl apply -f configmap.yaml
kubectl apply -f secret.yaml

# 3. 部署MySQL
echo "部署MySQL..."
kubectl apply -f mysql/
kubectl wait --for=condition=ready pod -l app=mysql -n webapp --timeout=300s

# 4. 部署Redis
echo "部署Redis..."
kubectl apply -f redis/
kubectl wait --for=condition=ready pod -l app=redis -n webapp --timeout=300s

# 5. 部署Backend
echo "部署Backend..."
kubectl apply -f backend/
kubectl wait --for=condition=ready pod -l app=backend -n webapp --timeout=300s

# 6. 部署Frontend
echo "部署Frontend..."
kubectl apply -f frontend/
kubectl wait --for=condition=ready pod -l app=frontend -n webapp --timeout=300s

# 7. 查看部署状态
echo "查看部署状态..."
kubectl get all -n webapp

# 8. 获取访问地址
echo "获取访问地址..."
kubectl get service frontend-service -n webapp

echo "部署完成!"

3.7 练习题

基础题

  1. 选择题
  2. Kubernetes中最小的可部署单元是什么?

    • A. Container
    • B. Pod
    • C. Service
    • D. Deployment
  3. 简答题

  4. 解释Pod、Service、Deployment的概念和关系。
  5. 说明Kubernetes的架构组件。

进阶题

  1. 实践题
  2. 创建一个包含3个副本的Deployment。
  3. 配置HPA实现自动扩缩容。
  4. 实现应用的滚动更新和回滚。

  5. 设计题

  6. 设计一个生产级的Kubernetes应用架构。
  7. 设计一个高可用的数据库部署方案。

答案

1. 选择题答案

  1. B(Pod是Kubernetes中最小的可部署单元)

2. 简答题答案

Pod、Service、Deployment的概念和关系: - Pod:最小的可部署单元,包含一个或多个容器 - Service:定义Pod的访问策略,提供稳定的网络端点 - Deployment:管理Pod和ReplicaSet,支持滚动更新和回滚

关系:Deployment创建和管理Pod,Service为Pod提供稳定的访问入口。

Kubernetes的架构组件: - 控制平面:API Server、etcd、Scheduler、Controller Manager - 工作节点:Kubelet、Kube-proxy、Container Runtime

3. 实践题答案

参见3.6节的完整实战项目。

4. 设计题答案

参见3.6.2-3.6.10节的完整项目设计。

3.8 面试准备

大厂面试题

字节跳动

  1. 解释Kubernetes的调度原理。
  2. 如何实现Kubernetes的高可用?
  3. Pod的生命周期有哪些状态?
  4. Service的类型和区别是什么?

腾讯

  1. Kubernetes的网络模型是什么?
  2. 如何实现Pod间通信?
  3. Deployment的更新策略有哪些?
  4. 如何排查Kubernetes问题?

阿里云

  1. ConfigMap和Secret的区别是什么?
  2. 如何实现Kubernetes的自动扩缩容?
  3. Kubernetes的存储方案有哪些?
  4. 如何监控Kubernetes集群?

📚 参考资料

🎯 本章小结

本章深入讲解了Kubernetes的核心技术,包括:

  1. Kubernetes的架构和核心组件
  2. Pod的生命周期和管理
  3. Service服务发现机制
  4. Deployment部署和更新策略
  5. Kubernetes的网络模型
  6. 完整的实战项目案例

通过本章学习,你掌握了Kubernetes的核心概念和操作,能够熟练使用Kubernetes进行容器编排。下一章将深入学习Kubernetes的进阶特性。