Kubernetes权威指南:从Docker到Kubernetes实践全接触(第4版)示例 Demo

82 阅读3分钟

架构图

graph TD
    User["外部用户"] --> |"http://<节点IP>:30001/demo/"| NodePort["NodePort Service (30001端口)"]
    subgraph " "
        NodePort --> |"转发流量"| MywebService["Service: myweb <br> 类型:  NodePort <br>端口: 8080 → 30001"]
        MywebService -->|"选择器: app=myweb"| RC["ReplicationController: myweb 副本数: 2"]
        RC --> Pod1["Pod: myweb-1"]
        RC --> Pod2["Pod: myweb-2"]
        Pod1 --> Container1["容器: Tomcat <br> kubeguide/tomcat-app:v1"]
        Pod2 --> Container2["容器: Tomcat <br> kubeguide/tomcat-app:v1"]
        Container1 -.->|"HTTP请求/SQL查询"| MySQLService["Service: mysql 类型: ClusterIP 端口: 3306"]
        Container2 -.->|"HTTP请求/SQL查询"| MySQLService
        MySQLService -->|"选择器: app=mysql"| MySQLPod["Pod: mysql"]
        MySQLPod --> MySQLContainer["容器: MySQL <br> 镜像: mysql:5.6 <br> 端口: 3306"]
        MySQLContainer --> PV["PersistentVolume <br> MySQL 数据存储"]
    end
    classDef service fill:#f9f,stroke:#333,stroke-width:1px
    classDef pod fill:#bbf,stroke:#333,stroke-width:1px
    classDef container fill:#bfb,stroke:#333,stroke-width:1px
    classDef volume fill:#fbb,stroke:#333,stroke-width:1px
    class MywebService,MySQLService service
    class Pod1,Pod2,MySQLPod pod
    class Container1,Container2,MySQLContainer container
    class PV volume

MySQL部署

mysql-pv.yaml - MySQL持久卷

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
  labels:
    type: local
spec:
  capacity:
    storage: 5Gi  # 存储容量为5GB
  accessModes:
    - ReadWriteOnce  # 只允许被一个节点以读写方式挂载
  persistentVolumeReclaimPolicy: Retain  # 当PVC被删除时保留数据
  hostPath:  # 使用本地存储,生产环境应使用网络存储
    path: "/mnt/data/mysql"

mysql-pvc.yaml - MySQL持久卷声明

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce  # 只允许被一个节点以读写方式挂载
  resources:
    requests:
      storage: 5Gi  # 请求5GB存储空间
  selector:
    matchLabels:
      type: local  # 选择带有type=local标签的PV

mysql-pod.yaml - MySQL Pod

apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    app: mysql  # 用于Service选择器的标签
spec:
  containers:
  - name: mysql
    image: mysql:5.6  # MySQL 5.6版本镜像
    ports:
    - containerPort: 3306  # MySQL默认端口
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"  # MySQL root密码,生产环境应使用Secret
    - name: MYSQL_DATABASE
      value: "demoapp"  # 自动创建的数据库名
    volumeMounts:
    - name: mysql-storage
      mountPath: /var/lib/mysql  # MySQL数据存储路径
  volumes:
  - name: mysql-storage
    persistentVolumeClaim:
      claimName: mysql-pvc  # 引用前面创建的PVC

mysql-service.yaml - MySQL Service

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  selector:
    app: mysql  # 选择带有app=mysql标签的Pod
  ports:
  - port: 3306  # Service暴露的端口
    targetPort: 3306  # Pod上的目标端口
  type: ClusterIP  # 集群内部访问,不对外暴露

Web应用部署

myweb-rc.yaml - Web应用的ReplicationController

apiVersion: v1
kind: ReplicationController
metadata:
  name: myweb
spec:
  replicas: 2  # 维持2个Pod副本
  selector:
    app: myweb  # 选择器,用于识别由此RC管理的Pod
  template:  # Pod模板
    metadata:
      labels:
        app: myweb  # Pod标签,与选择器匹配
    spec:
      containers:
      - name: tomcat
        image: kubeguide/tomcat-app:v1  # Tomcat应用镜像
        ports:
        - containerPort: 8080  # Tomcat默认端口
        env:
        - name: MYSQL_SERVICE_HOST  # MySQL服务主机环境变量
          value: "mysql"
        - name: MYSQL_SERVICE_PORT  # MySQL服务端口环境变量
          value: "3306"
        - name: MYSQL_ROOT_PASSWORD  # MySQL密码环境变量
          value: "password"  # 生产环境应使用Secret
        readinessProbe:  # 就绪探针,确保应用准备好接收流量
          httpGet:
            path: /demo/
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10

myweb-service.yaml - Web应用的NodePort Service

apiVersion: v1
kind: Service
metadata:
  name: myweb
spec:
  selector:
    app: myweb  # 选择带有app=myweb标签的Pod
  ports:
  - port: 8080  # Service内部端口
    targetPort: 8080  # Pod目标端口
    nodePort: 30001  # 节点端口,外部可通过<节点IP>:30001访问
  type: NodePort  # 服务类型为NodePort,允许外部访问

可选配置

configmap.yaml - 应用配置

apiVersion: v1
kind: ConfigMap
metadata:
  name: myweb-config
data:
  # 应用配置参数
  app.properties: |
    # 应用配置
    app.name=Demo Web Application
    app.description=Kubernetes示例应用
    
    # 数据库连接配置
    db.url=jdbc:mysql://mysql:3306/demoapp
    db.username=root

secret.yaml - 敏感信息

apiVersion: v1
kind: Secret
metadata:
  name: mysql-credentials
type: Opaque
data:
  # 使用base64编码的密码,实际使用时请替换
  # 可通过命令生成: echo -n "your-password" | base64
  password: cGFzc3dvcmQ=  # "password"的base64编码

部署说明

部署顺序

  1. 首先创建持久卷和持久卷声明:

    kubectl apply -f mysql-pv.yaml
    kubectl apply -f mysql-pvc.yaml
    
  2. 部署MySQL:

    kubectl apply -f mysql-pod.yaml
    kubectl apply -f mysql-service.yaml
    
  3. 部署Web应用:

    kubectl apply -f myweb-rc.yaml
    kubectl apply -f myweb-service.yaml
    
  4. 验证部署:

    kubectl get pods  # 检查Pod状态
    kubectl get services  # 检查Service状态
    
  5. 访问应用: 通过浏览器访问 http://<节点IP>:30001/demo/

注意事项

  • 生产环境中应使用Secret存储密码而非明文
  • 考虑为MySQL使用StatefulSet而非单个Pod
  • 生产环境应使用网络存储而非hostPath
  • 考虑添加资源限制(CPU/内存)和健康检查
  • 根据实际需求调整副本数量