第03章 Kubernetes核心¶
📚 章节概述¶
本章将深入讲解Kubernetes(K8s)的核心概念、架构设计、Pod管理、Service服务发现、Deployment部署等核心功能。通过本章学习,你将能够熟练使用Kubernetes进行容器编排,为生产环境部署打下坚实基础。
🎯 学习目标¶
完成本章后,你将能够:
- 理解Kubernetes的架构和核心组件
- 掌握Pod的生命周期和管理
- 熟练使用Service进行服务发现
- 掌握Deployment的部署和更新策略
- 理解Kubernetes的网络模型
- 能够编写Kubernetes YAML配置文件
- 掌握kubectl命令行工具的使用
3.1 Kubernetes概述¶
3.1.1 什么是Kubernetes¶
Kubernetes(简称K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用。它最初由Google设计,现在由CNCF(云原生计算基金会)维护。
Kubernetes的核心价值¶
- 自动化运维
- 自动部署和回滚
- 自动扩缩容
- 自动故障恢复
-
自动负载均衡
-
服务发现和负载均衡
- 内置服务发现机制
- 自动负载均衡
-
支持多种负载均衡策略
-
存储编排
- 自动挂载存储卷
- 支持多种存储后端
-
存储动态供应
-
自我修复
- 自动重启失败的容器
- 自动替换不健康的节点
-
自动杀死不响应的容器
-
密钥和配置管理
- 集中管理配置
- 密钥安全存储
- 配置热更新
3.1.2 Kubernetes架构¶
Kubernetes采用主从(Master-Node)架构,主要组件包括:
控制平面(Control Plane)¶
┌─────────────────────────────────────────────────────────┐
│ 控制平面 (Control Plane) │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ API Server │ │ Scheduler │ │ Controller │ │
│ │ │ │ │ │ Manager │ │
│ │ RESTful API │ │ 调度Pod到 │ │ 维护集群 │ │
│ │ 统一入口 │ │ 合适的节点 │ │ 期望状态 │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ └──────────────────┼──────────────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ etcd │ │
│ │ 键值存储 │ │
│ │ 存储集群状态 │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
核心组件详解¶
- API Server
- Kubernetes API的统一入口
- 处理REST操作
- 验证和配置数据
-
提供认证、授权、准入控制
-
etcd
- 高可用的键值存储
- 存储集群所有配置和状态
- 提供分布式锁和选举
-
数据一致性保证
-
Scheduler
- 调度Pod到合适的节点
- 考虑资源需求、策略约束
- 优化资源利用率
-
支持多种调度算法
-
Controller Manager
- 运行多种控制器
- 维护集群期望状态
- 处理节点故障
- 执行滚动更新
工作节点(Worker Node)¶
┌─────────────────────────────────────────────────────────┐
│ 工作节点 (Worker Node) │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Kubelet │ │ Kube-Proxy │ │ Container │ │
│ │ │ │ │ │ Runtime │ │
│ │ 管理Pod │ │ 网络代理 │ │ Docker/ │ │
│ │ 与API通信 │ │ 服务发现 │ │ containerd │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ └──────────────────┼──────────────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ Pods │ │
│ │ 容器组 │ │
│ │ 共享网络/存储 │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
节点组件详解¶
- Kubelet
- 与API Server通信
- 管理Pod生命周期
- 汇报节点状态
-
执行健康检查
-
Kube-proxy
- 维护网络规则
- 实现Service负载均衡
- 支持多种代理模式
-
处理网络策略
-
Container Runtime
- 运行容器
- 拉取镜像
- 管理容器生命周期
- 支持CRI接口
3.1.3 Kubernetes工作流程¶
用户提交YAML配置
│
▼
API Server
│
▼
etcd存储
│
▼
Controller Manager
(检测期望状态)
│
▼
Scheduler
(调度Pod到节点)
│
▼
Kubelet
(在节点上创建Pod)
│
▼
Container Runtime
(启动容器)
│
▼
运行状态
│
▼
Controller Manager
(监控并维护状态)
3.2 安装Kubernetes¶
3.2.1 使用Minikube(本地开发)¶
# 安装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节点安装¶
# 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节点加入¶
# 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¶
# 安装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¶
# 安装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的特点¶
- 共享网络
- 同一Pod内的容器共享网络命名空间
- 容器间可以通过localhost通信
-
共享端口空间
-
共享存储
- 可以挂载共享的Volume
-
容器间共享数据
-
原子性
- Pod作为一个整体被调度
-
同一Pod的容器总是在同一节点
-
临时性
- Pod是临时的、可替换的
- IP地址会变化
- 不保证持久存储
3.3.2 Pod生命周期¶
Pod状态说明¶
- Pending
- Pod已创建,但容器还未启动
-
正在下载镜像或调度中
-
Running
- Pod已绑定到节点
- 所有容器都已创建
-
至少有一个容器正在运行
-
Succeeded
- Pod中的所有容器都已成功终止
-
不会重启
-
Failed
- Pod中的所有容器都已终止
-
至少有一个容器以失败状态终止
-
Unknown
- 无法获取Pod状态
- 通常是由于通信问题
3.3.3 创建Pod¶
基本Pod配置¶
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¶
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¶
# 创建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资源管理¶
资源请求和限制¶
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(存活探针)¶
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(就绪探针)¶
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(启动探针)¶
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的类型¶
- ClusterIP(默认)
- 集群内部可访问
- 分配集群内部IP
-
适用于内部服务
-
NodePort
- 通过节点IP和端口访问
- 每个节点开放相同端口
-
适用于开发测试
-
LoadBalancer
- 通过云服务商的负载均衡器访问
- 分配外部IP
-
适用于生产环境
-
ExternalName
- 映射到外部DNS名称
- 不创建代理
- 适用于外部服务
3.4.2 创建Service¶
ClusterIP Service¶
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¶
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¶
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操作¶
# 创建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¶
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的功能¶
- Pod副本管理
- 维护指定数量的Pod副本
- 自动替换失败的Pod
-
支持水平扩展
-
滚动更新
- 逐步替换旧版本Pod
- 零停机更新
-
可控制更新策略
-
回滚
- 快速回滚到之前版本
- 保留历史版本
-
支持版本对比
-
暂停和恢复
- 暂停更新过程
- 恢复更新
- 调试更新问题
3.5.2 创建Deployment¶
基本Deployment¶
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¶
# 创建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 扩缩容¶
手动扩缩容¶
# 扩展到5个副本
kubectl scale deployment nginx-deployment --replicas=5
# 缩减到2个副本
kubectl scale deployment nginx-deployment --replicas=2
# 查看扩缩容状态
kubectl get pods -l app=nginx
自动扩缩容(HPA)¶
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%时扩容
# 创建HPA
kubectl apply -f hpa.yaml
# 查看HPA
kubectl get hpa
# 查看HPA详情
kubectl describe hpa nginx-hpa
3.5.4 滚动更新¶
更新镜像版本¶
# 更新镜像
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
更新策略配置¶
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 回滚¶
回滚到之前版本¶
# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment
# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2
# 查看回滚状态
kubectl rollout status deployment/nginx-deployment
暂停和恢复¶
# 暂停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 项目结构¶
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配置¶
apiVersion: v1
kind: Namespace # 命名空间:用于资源隔离和多租户管理
metadata:
name: webapp # 命名空间名称
labels:
name: webapp
environment: production # 标识生产环境,便于按环境筛选
3.6.4 ConfigMap配置¶
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配置¶
# ⚠️ 安全警告:以下配置包含硬编码密码,仅用于演示目的。
# 在生产环境中,请务必使用环境变量或密钥管理服务来存储敏感信息。
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部署¶
# 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 # 引用持久卷声明,确保数据持久化
# 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 # 数据库仅集群内部访问,不对外暴露
# 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部署¶
# 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)
# 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部署¶
# 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
# 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 # 仅集群内部访问
# 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部署¶
# 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
# 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 部署脚本¶
#!/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 练习题¶
基础题¶
- 选择题
-
Kubernetes中最小的可部署单元是什么?
- A. Container
- B. Pod
- C. Service
- D. Deployment
-
简答题
- 解释Pod、Service、Deployment的概念和关系。
- 说明Kubernetes的架构组件。
进阶题¶
- 实践题
- 创建一个包含3个副本的Deployment。
- 配置HPA实现自动扩缩容。
-
实现应用的滚动更新和回滚。
-
设计题
- 设计一个生产级的Kubernetes应用架构。
- 设计一个高可用的数据库部署方案。
答案¶
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 面试准备¶
大厂面试题¶
字节跳动¶
- 解释Kubernetes的调度原理。
- 如何实现Kubernetes的高可用?
- Pod的生命周期有哪些状态?
- Service的类型和区别是什么?
腾讯¶
- Kubernetes的网络模型是什么?
- 如何实现Pod间通信?
- Deployment的更新策略有哪些?
- 如何排查Kubernetes问题?
阿里云¶
- ConfigMap和Secret的区别是什么?
- 如何实现Kubernetes的自动扩缩容?
- Kubernetes的存储方案有哪些?
- 如何监控Kubernetes集群?
📚 参考资料¶
- Kubernetes官方文档:https://kubernetes.io/docs/
- Kubernetes API参考:https://kubernetes.io/docs/reference/
- 《Kubernetes权威指南》
- 《Kubernetes in Action》
- Kubernetes最佳实践:https://kubernetes.io/docs/concepts/configuration/overview/
🎯 本章小结¶
本章深入讲解了Kubernetes的核心技术,包括:
- Kubernetes的架构和核心组件
- Pod的生命周期和管理
- Service服务发现机制
- Deployment部署和更新策略
- Kubernetes的网络模型
- 完整的实战项目案例
通过本章学习,你掌握了Kubernetes的核心概念和操作,能够熟练使用Kubernetes进行容器编排。下一章将深入学习Kubernetes的进阶特性。