第04章 Kubernetes进阶¶
📚 章节概述¶
本章将深入讲解Kubernetes的进阶特性,包括ConfigMap和Secret配置管理、Ingress入口控制器、Helm包管理、StatefulSet有状态应用、DaemonSet守护进程集等。通过本章学习,你将能够掌握Kubernetes的高级功能,应对复杂的生产环境需求。
🎯 学习目标¶
完成本章后,你将能够:
- 熟练使用ConfigMap和Secret管理配置
- 掌握Ingress的配置和使用
- 了解Helm包管理器的使用
- 掌握StatefulSet有状态应用部署
- 理解DaemonSet的使用场景
- 掌握Kubernetes的网络策略
- 能够设计复杂的生产级Kubernetes架构
4.1 ConfigMap配置管理¶
4.1.1 ConfigMap概述¶
ConfigMap用于存储非敏感的配置数据,以键值对的形式提供给Pod使用。
ConfigMap的特点¶
- 解耦配置
- 配置与镜像分离
- 支持配置热更新
-
便于版本管理
-
多种数据格式
- 键值对
- 完整的配置文件
-
JSON/YAML格式
-
灵活的注入方式
- 环境变量
- 命令行参数
- 配置文件挂载
4.1.2 创建ConfigMap¶
从字面值创建¶
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config # ConfigMap 名称
namespace: default
data:
# 数据库连接配置
database_host: "mysql-service"
database_port: "3306"
database_name: "appdb"
# Redis 缓存配置
redis_host: "redis-service"
redis_port: "6379"
# 应用运行时配置
app_env: "production"
log_level: "info"
debug_mode: "false"
从文件创建¶
# 从单个文件创建
kubectl create configmap nginx-config --from-file=nginx.conf
# 从目录创建
kubectl create configmap app-config --from-file=./config/
# 从多个文件创建
kubectl create configmap app-config \
--from-file=app.properties \
--from-file=logback.xml
从命令行创建¶
# 从字面值创建
kubectl create configmap app-config \
--from-literal=database_host=mysql \
--from-literal=database_port=3306 \
--from-literal=app_env=production
4.1.3 使用ConfigMap¶
作为环境变量¶
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: app
image: nginx:1.27
env:
# 从 ConfigMap 中注入单个键值作为环境变量
- name: DATABASE_HOST # Pod 中的环境变量名
valueFrom:
configMapKeyRef:
name: app-config # 引用的 ConfigMap 名称
key: database_host # ConfigMap 中的键
- name: DATABASE_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: database_port
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: app_env
批量注入环境变量¶
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: app
image: nginx:1.27
# 一次性将 ConfigMap 中所有键值对注入为环境变量
envFrom:
- configMapRef:
name: app-config # 引用整个 ConfigMap
作为命令行参数¶
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: app
image: nginx:1.27
command: ["/bin/sh", "-c"]
args: ["echo $(DATABASE_HOST) $(DATABASE_PORT)"]
env:
- name: DATABASE_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database_host
- name: DATABASE_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: database_port
作为配置文件挂载¶
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: app
image: nginx:1.27
volumeMounts:
- name: config-volume
mountPath: /etc/config # 挂载到容器内的路径
readOnly: true # 只读挂载,防止容器修改配置
volumes:
- name: config-volume
configMap:
name: app-config # 引用的 ConfigMap
items: # 选择性挂载特定的键
- key: nginx.conf
path: nginx.conf # 映射为容器内的文件名
- key: app.properties
path: app.properties
4.1.4 ConfigMap热更新¶
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
server.port=8080
server.host=0.0.0.0
database.url=jdbc:mysql://localhost:3306/appdb
log.level=INFO
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
spec:
containers:
- name: app
image: myapp:v1.0
volumeMounts:
- name: config-volume
mountPath: /etc/config # ConfigMap 挂载点
volumes:
- name: config-volume
configMap:
name: app-config # ConfigMap 更新后,挂载的文件会自动更新
注意:ConfigMap更新后,挂载的配置文件会自动更新,但环境变量不会自动更新,需要重启Pod。
4.2 Secret密钥管理¶
4.2.1 Secret概述¶
Secret用于存储敏感信息,如密码、OAuth令牌、SSH密钥等。
Secret的类型¶
- Opaque:通用类型,默认类型
- kubernetes.io/service-account-token:服务账号令牌
- kubernetes.io/dockercfg:Docker registry认证
- kubernetes.io/dockerconfigjson:Docker registry认证(JSON格式)
- kubernetes.io/basic-auth:基本认证
- kubernetes.io/ssh-auth:SSH认证
- kubernetes.io/tls:TLS证书
- bootstrap.kubernetes.io/token:bootstrap令牌
4.2.2 创建Secret¶
从命令行创建¶
# 通用Secret
kubectl create secret generic app-secret \
--from-literal=username=admin \
--from-literal=password=secretpassword
# 从文件创建
kubectl create secret generic ssh-key \
--from-file=ssh-privatekey=/path/to/id_rsa \
--from-file=ssh-publickey=/path/to/id_rsa.pub
# TLS Secret
kubectl create secret tls tls-secret \
--cert=path/to/cert.crt \
--key=path/to/cert.key
# Docker registry Secret
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=user \
--docker-password=password \
--docker-email=user@example.com
从YAML创建¶
# ⚠️ 安全警告:以下配置包含硬编码密码,仅用于演示目的。
# 在生产环境中,请务必使用环境变量或密钥管理服务来存储敏感信息。
apiVersion: v1
kind: Secret
metadata:
name: app-secret
namespace: default
type: Opaque
data:
username: YWRtaW4= # base64编码的admin
password: c2VjcmV0cGFzc3dvcmQ= # base64编码的secretpassword
database_url: amRiYzpteXNxbDovL2xvY2FsaG9zdDozMzA2L2FwcGRi
编码示例:
# 编码
echo -n 'admin' | base64
echo -n 'secretpassword' | base64
# 解码
echo 'YWRtaW4=' | base64 -d
4.2.3 使用Secret¶
作为环境变量¶
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: app
image: nginx:1.27
env:
# 从 Secret 中注入敏感信息作为环境变量
- name: USERNAME
valueFrom:
secretKeyRef:
name: app-secret # 引用的 Secret 名称
key: username # Secret 中的键
- name: PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: password
批量注入环境变量¶
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: app
image: nginx:1.27
envFrom:
- secretRef:
name: app-secret
作为配置文件挂载¶
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: app
image: nginx:1.27
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets # Secret 挂载到容器内的路径
readOnly: true # 必须只读,保护敏感数据
volumes:
- name: secret-volume
secret:
secretName: app-secret # 引用的 Secret
items: # 按键映射为单独的文件
- key: username
path: username.txt # 挂载为 /etc/secrets/username.txt
- key: password
path: password.txt # 挂载为 /etc/secrets/password.txt
拉取私有镜像¶
apiVersion: v1
kind: Pod
metadata:
name: private-pod
spec:
containers:
- name: app
image: registry.example.com/myapp:v1.0 # 私有镜像地址
imagePullSecrets:
- name: regcred # 引用 Docker Registry 认证 Secret
4.2.4 Secret最佳实践¶
- 使用RBAC限制访问
- 定期轮换Secret
- 使用外部密钥管理系统(如Vault)
- 避免在日志中打印Secret
- 使用加密存储(etcd加密)
4.3 Ingress入口控制器¶
4.3.1 Ingress概述¶
Ingress是Kubernetes的API对象,管理外部访问集群内服务的规则,提供HTTP和HTTPS路由。
Ingress vs Service¶
| 特性 | Service | Ingress |
|---|---|---|
| 协议 | TCP/UDP | HTTP/HTTPS |
| 路由 | 基于端口 | 基于主机名/路径 |
| 负载均衡 | L4 | L7 |
| TLS | 不支持 | 支持 |
| 复杂度 | 简单 | 复杂 |
4.3.2 Ingress Controller¶
Ingress Controller是实现Ingress规则的组件,常见的有:
- Nginx Ingress Controller
- Traefik
- HAProxy
- Contour
- AWS ALB Ingress Controller
安装Nginx Ingress Controller¶
# 添加Helm仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# 安装
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespace
# 验证安装
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx
4.3.3 创建Ingress¶
基本Ingress¶
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: basic-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # URL 重写目标
spec:
ingressClassName: nginx # 指定使用的 Ingress Controller
rules:
- host: app.example.com # 域名规则
http:
paths:
- path: / # 匹配根路径
pathType: Prefix # 前缀匹配模式
backend:
service:
name: app-service # 后端服务名称
port:
number: 80 # 服务端口
多路径路由¶
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-path-ingress
namespace: default
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
# 多路径路由:不同 URL 路径转发到不同后端服务
- path: /api # API 请求转发到 api-service
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8000
- path: /web # Web 页面转发到 web-service
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- path: /static # 静态资源转发到 static-service
pathType: Prefix
backend:
service:
name: static-service
port:
number: 80
多主机路由¶
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host-ingress
namespace: default
spec:
ingressClassName: nginx
# 多主机路由:不同域名转发到不同服务
rules:
- host: api.example.com # API 域名转发到 api-service
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8000
- host: web.example.com # Web 域名转发到 web-service
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
TLS配置¶
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
namespace: default
spec:
ingressClassName: nginx
# TLS 配置:启用 HTTPS 加密访问
tls:
- hosts:
- app.example.com # 开启 TLS 的域名
secretName: tls-secret # 存储 TLS 证书的 Secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
4.3.4 Ingress注解¶
常用注解¶
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: annotated-ingress
namespace: default
annotations:
# 重写目标
nginx.ingress.kubernetes.io/rewrite-target: /$2
# SSL重定向
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
# 限流
nginx.ingress.kubernetes.io/limit-rps: "10"
# CORS
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
# 超时设置
nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
# 代理缓冲
nginx.ingress.kubernetes.io/proxy-buffering: "on"
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
# WebSocket
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
nginx.ingress.kubernetes.io/proxy-set-headers: "Upgrade: $http_upgrade\nConnection: upgrade"
# 白名单
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
# 认证
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8000
4.4 Helm包管理¶
4.4.1 Helm概述¶
Helm是Kubernetes的包管理器,类似于Linux的yum或apt,用于管理Kubernetes应用。
Helm的核心概念¶
- Chart:Helm包,包含运行应用所需的所有资源
- Repository:Chart仓库,存储和分发Chart
- Release:Chart的实例化部署
- Config:配置值,用于自定义Chart
4.4.2 安装Helm¶
# 下载Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash # |管道:将前一命令的输出作为后一命令的输入
# 验证安装
helm version
# 添加官方仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# 搜索Chart
helm search repo nginx
4.4.3 创建Chart¶
# 创建Chart
helm create mychart
# Chart结构
mychart/
├── Chart.yaml # Chart元数据
├── values.yaml # 默认配置值
├── charts/ # 依赖的Chart
├── templates/ # Kubernetes资源模板
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ └── _helpers.tpl # 模板助手
└── templates/NOTES.txt # 使用说明
Chart.yaml¶
apiVersion: v2
name: mychart
description: A Helm chart for Kubernetes # Chart 描述
type: application # 类型:application 或 library
version: 0.1.0 # Chart 版本号
appVersion: "1.0" # 应用版本号
keywords:
- web
- application
maintainers: # 维护者信息
- name: Your Name
email: your.email@example.com
values.yaml¶
# 默认配置值
replicaCount: 3
image:
repository: nginx
pullPolicy: IfNotPresent
tag: "1.27"
service:
type: ClusterIP
port: 80
podSecurityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
ingress:
enabled: false
className: "nginx"
annotations: {}
hosts:
- host: chart-example.local
paths:
- path: /
pathType: Prefix
tls: []
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
templates/deployment.yaml¶
apiVersion: apps/v1
kind: Deployment
metadata:
# 使用模板函数生成完整名称(发布名-Chart名)
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
spec:
# 副本数从 values.yaml 中读取,实现可配置化
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "mychart.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "mychart.selectorLabels" . | nindent 8 }}
spec:
# Pod 安全上下文(可选配置)
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
# 镜像地址:从 values.yaml 拼接 repository:tag
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
# 容器安全上下文(可选配置)
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 10 }}
{{- end }}
ports:
- name: http
containerPort: {{ .Values.service.port }}
protocol: TCP
# 存活探针:检测容器是否还在运行
livenessProbe:
httpGet:
path: /
port: http
# 就绪探针:检测容器是否准备好接受流量
readinessProbe:
httpGet:
path: /
port: http
# 资源限制从 values.yaml 中读取
resources:
{{- toYaml .Values.resources | nindent 10 }}
templates/service.yaml¶
apiVersion: v1
kind: Service
metadata:
# 服务名称使用模板函数自动生成
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }} # 服务类型(ClusterIP/NodePort/LoadBalancer)
ports:
- port: {{ .Values.service.port }} # 服务端口
targetPort: http # 目标端口(对应容器的命名端口)
protocol: TCP
name: http
selector:
# 通过标签选择器关联到对应的 Pod
{{- include "mychart.selectorLabels" . | nindent 4 }}
4.4.4 使用Helm¶
安装Chart¶
# 安装Chart
helm install my-release ./mychart
# 指定配置值
helm install my-release ./mychart --set replicaCount=5
# 使用配置文件
helm install my-release ./mychart -f custom-values.yaml
# 查看Release
helm list
helm status my-release
更新Release¶
# 更新Release
helm upgrade my-release ./mychart
# 更新配置
helm upgrade my-release ./mychart --set replicaCount=10
# 回滚Release
helm rollback my-release
helm rollback my-release 2 # 回滚到第2个版本
卸载Release¶
4.5 StatefulSet有状态应用¶
4.5.1 StatefulSet概述¶
StatefulSet用于管理有状态应用,如数据库、消息队列等。
StatefulSet的特点¶
- 稳定的网络标识
- 每个Pod有唯一的、稳定的网络标识
-
格式:
<statefulset-name>-<ordinal> -
稳定的持久化存储
- 每个Pod绑定独立的PVC
-
Pod重新调度后仍能访问相同的存储
-
有序的部署和扩展
- 按顺序部署Pod(0, 1, 2, ...)
-
按顺序删除Pod(N, N-1, N-2, ...)
-
有序的滚动更新
- 按逆序更新Pod(N, N-1, N-2, ...)
4.5.2 创建StatefulSet¶
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: default
spec:
serviceName: mysql-headless # 关联的 Headless Service,提供稳定网络标识
replicas: 3 # 3 个副本,按序号 0/1/2 创建
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.4
ports:
- containerPort: 3306
name: mysql
env:
# 从 Secret 中获取数据库 root 密码
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: root-password
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql # 数据持久化挂载点
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
# 存活探针:检测 MySQL 是否运行
livenessProbe:
exec:
command: ["mysqladmin", "ping", "-h", "localhost"]
initialDelaySeconds: 30 # 启动后 30s 开始探测
periodSeconds: 10 # 每 10s 探测一次
# 就绪探针:检测 MySQL 是否可接受流量
readinessProbe:
exec:
command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
initialDelaySeconds: 5
periodSeconds: 5
# PVC 模板:为每个 Pod 自动创建独立的持久化存储
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ] # 单节点读写
storageClassName: "standard"
resources:
requests:
storage: 10Gi # 每个副本 10Gi 存储
4.5.3 Headless Service¶
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
namespace: default
spec:
clusterIP: None # Headless Service:无集群 IP,直接解析到 Pod IP
selector:
app: mysql
ports:
- port: 3306
name: mysql
# Pod 的 DNS 格式:mysql-0.mysql-headless.default.svc.cluster.local
4.5.4 StatefulSet操作¶
# 创建StatefulSet
kubectl apply -f statefulset.yaml
# 查看StatefulSet
kubectl get statefulsets
kubectl get sts
# 查看Pod
kubectl get pods -l app=mysql
# 查看PVC
kubectl get pvc
# 扩展StatefulSet
kubectl scale statefulset mysql --replicas=5
# 删除特定Pod
kubectl delete pod mysql-2
# 滚动更新
kubectl set image statefulset mysql mysql=mysql:8.4.0
# 查看更新状态
kubectl rollout status statefulset/mysql
4.6 DaemonSet守护进程集¶
4.6.1 DaemonSet概述¶
DaemonSet确保在每个节点上运行一个Pod副本,常用于日志收集、监控代理等。
DaemonSet的使用场景¶
- 日志收集:Fluentd、Filebeat
- 监控代理:Node Exporter、Datadog Agent
- 网络插件:Calico、Flannel
- 存储插件:Ceph、GlusterFS
4.6.2 创建DaemonSet¶
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
labels:
app: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
hostNetwork: true # 使用宿主机网络,直接采集节点网络指标
hostPID: true # 访问宿主机 PID 命名空间
containers:
- name: node-exporter
image: prom/node-exporter:latest
args:
- '--path.procfs=/host/proc' # 指定宿主机 proc 路径
- '--path.sysfs=/host/sys' # 指定宿主机 sys 路径
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)' # 排除系统目录
ports:
- name: metrics
containerPort: 9100
hostPort: 9100 # 映射到宿主机端口,便于 Prometheus 拉取
volumeMounts:
# 挂载宿主机的 /proc 和 /sys 目录用于采集指标
- name: proc
mountPath: /host/proc
- name: sys
mountPath: /host/sys
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
# 容忍所有污点,确保在每个节点都能调度
tolerations:
- effect: NoSchedule
operator: Exists
- effect: NoExecute
operator: Exists
4.6.3 DaemonSet操作¶
# 创建DaemonSet
kubectl apply -f daemonset.yaml
# 查看DaemonSet
kubectl get daemonsets
kubectl get ds
# 查看Pod
kubectl get pods -l app=node-exporter
# 更新DaemonSet
kubectl set image daemonset node-exporter node-exporter=prom/node-exporter:v1.5.0
# 查看更新状态
kubectl rollout status daemonset/node-exporter
4.7 网络策略¶
4.7.1 网络策略概述¶
NetworkPolicy用于控制Pod之间的网络流量,实现网络隔离。
网络策略的类型¶
- Ingress规则:控制入站流量
- Egress规则:控制出站流量
- Both规则:同时控制入站和出站流量
4.7.2 创建网络策略¶
默认拒绝所有入站流量¶
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: default
spec:
podSelector: {} # 空选择器:匹配命名空间内所有 Pod
policyTypes:
- Ingress # 仅控制入站流量,未指定 ingress 规则则全部拒绝
允许特定Pod访问¶
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: default
spec:
# 目标 Pod:带有 app=backend 标签的 Pod
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
# 允许来源:仅允许带有 app=frontend 标签的 Pod 访问
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8000 # 仅允许访问 8000 端口
允许特定命名空间访问¶
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-namespace-access
namespace: default
spec:
# 目标 Pod:带有 app=backend 标签的 Pod
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
# 允许来自带有 name=frontend 标签的命名空间的所有 Pod
- namespaceSelector:
matchLabels:
name: frontend
ports:
- protocol: TCP
port: 8000
控制出站流量¶
apiVersion: networking.k8s.io/v1 # apiVersion指定K8s API版本
kind: NetworkPolicy # kind指定资源类型
metadata:
name: allow-dns-access
namespace: default
spec: # spec定义资源的期望状态
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress # 控制出站流量
egress:
# 规则1:允许 DNS 查询(必须允许,否则服务发现失败)
- to:
- namespaceSelector: {} # 所有命名空间
ports:
- protocol: UDP
port: 53 # DNS 端口
# 规则2:允许 HTTPS 出站访问,排除元数据服务地址
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32 # 排除云平台元数据服务(安全最佳实践)
ports:
- protocol: TCP
port: 443 # 仅允许 HTTPS
4.8 完整实战项目¶
4.8.1 项目概述¶
部署一个完整的微服务应用,包括: - ConfigMap配置管理 - Secret密钥管理 - Ingress入口控制器 - StatefulSet数据库 - DaemonSet监控 - 网络策略
4.8.2 项目结构¶
k8s-advanced-project/
├── namespace.yaml
├── configmap.yaml
├── secret.yaml
├── network-policy.yaml
├── mysql/
│ ├── statefulset.yaml
│ ├── service.yaml
│ └── headless-service.yaml
├── redis/
│ ├── statefulset.yaml
│ └── service.yaml
├── backend/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── hpa.yaml
├── frontend/
│ ├── deployment.yaml
│ └── service.yaml
├── monitoring/
│ └── daemonset.yaml
└── ingress/
└── ingress.yaml
4.8.3 部署脚本¶
#!/bin/bash
# 部署脚本
set -e
echo "开始部署高级Kubernetes应用..."
# 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. 创建网络策略
echo "创建网络策略..."
kubectl apply -f network-policy.yaml
# 4. 部署MySQL StatefulSet
echo "部署MySQL..."
kubectl apply -f mysql/
kubectl wait --for=condition=ready pod -l app=mysql -n webapp --timeout=600s
# 5. 部署Redis StatefulSet
echo "部署Redis..."
kubectl apply -f redis/
kubectl wait --for=condition=ready pod -l app=redis -n webapp --timeout=600s
# 6. 部署Backend
echo "部署Backend..."
kubectl apply -f backend/
kubectl wait --for=condition=ready pod -l app=backend -n webapp --timeout=300s
# 7. 部署Frontend
echo "部署Frontend..."
kubectl apply -f frontend/
kubectl wait --for=condition=ready pod -l app=frontend -n webapp --timeout=300s
# 8. 部署Monitoring DaemonSet
echo "部署Monitoring..."
kubectl apply -f monitoring/
# 9. 创建Ingress
echo "创建Ingress..."
kubectl apply -f ingress/
# 10. 查看部署状态
echo "查看部署状态..."
kubectl get all -n webapp
echo "部署完成!"
4.9 练习题¶
基础题¶
- 选择题
-
ConfigMap和Secret的主要区别是什么?
- A. ConfigMap用于存储敏感数据
- B. Secret数据是明文存储
- C. Secret数据是base64编码
- D. ConfigMap不能挂载为文件
-
简答题
- 解释Ingress的作用和使用场景。
- 说明StatefulSet和Deployment的区别。
进阶题¶
- 实践题
- 创建一个包含ConfigMap和Secret的完整应用。
- 配置Ingress实现多路径路由。
-
部署一个StatefulSet数据库。
-
设计题
- 设计一个生产级的微服务架构。
- 设计一个高可用的数据库部署方案。
答案¶
1. 选择题答案¶
- C(Secret数据是base64编码,ConfigMap是明文)
2. 简答题答案¶
Ingress的作用和使用场景: - 作用:管理外部访问集群内服务的HTTP/HTTPS路由 - 使用场景:多域名路由、多路径路由、TLS终止、负载均衡
StatefulSet和Deployment的区别: - StatefulSet:有状态应用,稳定的网络标识和存储,有序部署 - Deployment:无状态应用,Pod标识不固定,并发部署
3. 实践题答案¶
参见4.8节的完整实战项目。
4. 设计题答案¶
参见4.8节的完整项目设计。
4.10 面试准备¶
大厂面试题¶
字节跳动¶
- ConfigMap和Secret的区别是什么?
- Ingress的工作原理是什么?
- StatefulSet的使用场景是什么?
- 如何实现Kubernetes的网络隔离?
腾讯¶
- Helm的Chart结构是怎样的?
- StatefulSet的有序部署是如何实现的?
- DaemonSet的使用场景有哪些?
- 如何实现Kubernetes的灰度发布?
阿里云¶
- ConfigMap热更新的机制是什么?
- Ingress Controller的选择标准是什么?
- 如何实现Kubernetes的配置管理?
- StatefulSet的存储管理是怎样的?
📚 参考资料¶
- Kubernetes官方文档:https://kubernetes.io/docs/
- Helm官方文档:https://helm.sh/docs/
- Nginx Ingress Controller:https://kubernetes.github.io/ingress-nginx/
- 《Kubernetes权威指南》
- 《Kubernetes in Action》
🎯 本章小结¶
本章深入讲解了Kubernetes的进阶特性,包括:
- ConfigMap和Secret配置管理
- Ingress入口控制器
- Helm包管理器
- StatefulSet有状态应用
- DaemonSet守护进程集
- 网络策略
- 完整的实战项目案例
通过本章学习,你掌握了Kubernetes的高级功能,能够应对复杂的生产环境需求。下一章将深入学习CI/CD流水线技术。