架构图
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编码
部署说明
部署顺序
-
首先创建持久卷和持久卷声明:
kubectl apply -f mysql-pv.yaml kubectl apply -f mysql-pvc.yaml
-
部署MySQL:
kubectl apply -f mysql-pod.yaml kubectl apply -f mysql-service.yaml
-
部署Web应用:
kubectl apply -f myweb-rc.yaml kubectl apply -f myweb-service.yaml
-
验证部署:
kubectl get pods # 检查Pod状态 kubectl get services # 检查Service状态
-
访问应用: 通过浏览器访问
http://<节点IP>:30001/demo/
注意事项
- 生产环境中应使用Secret存储密码而非明文
- 考虑为MySQL使用StatefulSet而非单个Pod
- 生产环境应使用网络存储而非hostPath
- 考虑添加资源限制(CPU/内存)和健康检查
- 根据实际需求调整副本数量