如何将Minikube中Flask应用节点连接至MySQL容器数据库?Docker Link转K8s实现
嘿,我来帮你一步步解决这个问题——把Minikube里的Flask应用连接到宿主机上的MySQL Docker容器。之前用Docker的--link是容器间的直接关联,但在Kubernetes里得换个思路,毕竟Minikube是个独立的集群环境,得先让它能访问到外部的MySQL,再配置应用的连接参数。
默认情况下,MySQL容器只允许本地(容器内部或宿主机localhost)访问,得先调整配置让它能被Minikube集群访问:
修改MySQL绑定地址:
如果是重新启动MySQL容器,加上--bind-address=0.0.0.0参数,让它监听所有网卡:docker run -d --name db \ -e MYSQL_ROOT_PASSWORD=your_root_password \ -e MYSQL_DATABASE=your_target_db \ -p 3306:3306 \ mysql:latest \ --bind-address=0.0.0.0要是容器已经在运行,你可以进入容器修改
/etc/mysql/mysql.conf.d/mysqld.cnf里的bind-address为0.0.0.0,然后重启容器:docker restart db。创建允许外部访问的数据库用户:
进入MySQL容器,创建一个能从Minikube集群访问的用户(测试阶段可以允许所有IP,生产环境建议限制IP段):docker exec -it db mysql -u root -p输入root密码后执行SQL:
CREATE USER 'flask_user'@'%' IDENTIFIED BY 'your_app_db_password'; GRANT ALL PRIVILEGES ON your_target_db.* TO 'flask_user'@'%'; FLUSH PRIVILEGES;
Minikube运行在独立的环境(虚拟机或容器)里,不能直接用localhost访问宿主机的MySQL,得用宿主机在Minikube网络中的IP:
- 如果你用的是Docker驱动(最常见),宿主机IP通常是Docker网桥的网关地址
172.17.0.1,可以在Minikube里验证:minikube ssh ping 172.17.0.1 - 通用获取方式:在Minikube节点中查询默认网关,这个就是宿主机IP:
记下这个IP(比如minikube ssh "route -n | grep '^0.0.0.0' | awk '{print \$2}'"192.168.49.1),后面会用到。
Kubernetes推荐用ConfigMap存储非敏感配置(比如数据库地址、用户名、库名),用Secret存储敏感信息(比如密码),这样更安全也更易维护:
创建ConfigMap:
新建db-config.yaml文件:apiVersion: v1 kind: ConfigMap metadata: name: db-config data: DB_HOST: "192.168.49.1" # 替换成你刚才拿到的宿主机IP DB_USER: "flask_user" DB_NAME: "your_target_db"应用到集群:
kubectl apply -f db-config.yaml创建Secret:
用命令直接创建(避免明文写在YAML里):kubectl create secret generic db-secret \ --from-literal=DB_PASSWORD=your_app_db_password
现在编写Flask应用的Deployment YAML,把ConfigMap和Secret的内容作为环境变量注入到容器中,这样Flask应用就能读取这些参数连接MySQL了:
新建flask-deployment.yaml:
apiVersion: apps/v1 kind: Deployment metadata: name: acts-app-deployment spec: replicas: 1 selector: matchLabels: app: acts-app template: metadata: labels: app: acts-app spec: containers: - name: acts-app image: acts-app:latest # 本地镜像需先加载到Minikube:`minikube image load acts-app` ports: - containerPort: 80 env: # 从ConfigMap读取非敏感配置 - name: DB_HOST valueFrom: configMapKeyRef: name: db-config key: DB_HOST - name: DB_USER valueFrom: configMapKeyRef: name: db-config key: DB_USER - name: DB_NAME valueFrom: configMapKeyRef: name: db-config key: DB_NAME # 从Secret读取敏感密码 - name: DB_PASSWORD valueFrom: secretKeyRef: name: db-secret key: DB_PASSWORD --- # 可选:创建Service让外部能访问Flask应用 apiVersion: v1 kind: Service metadata: name: acts-app-service spec: type: NodePort selector: app: acts-app ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 30007 # 可选,不指定则K8s自动分配端口
部署到Minikube:
kubectl apply -f flask-deployment.yaml
- 先检查Pod是否正常运行:
kubectl get pods - 进入Flask Pod测试数据库连接(如果容器里有MySQL客户端):
kubectl exec -it <your-pod-name> -- /bin/bash # 测试连接 mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD $DB_NAME - 或者查看Flask应用的日志,确认是否连接成功:
kubectl logs <your-pod-name>
- 如果Minikube用的是VirtualBox驱动,宿主机IP通常是
192.168.99.1,可以用minikube ip查看Minikube节点IP,宿主机就是同网段的第一个IP。 - 确保宿主机防火墙没有拦截3306端口,Minikube能正常访问该端口。
- 如果你用的是本地Docker镜像,一定要用
minikube image load acts-app把镜像加载到Minikube环境中,否则Kubernetes会尝试从公共镜像仓库拉取,导致镜像找不到。
内容的提问来源于stack exchange,提问作者Hari Charan

