K8s同命名空间下auth Pod无法连接mysql Pod问题排查求助
问题描述
我有一个auth Pod,需要与同命名空间下的mysql Pod通信,二者均处于mp3命名空间中。
mp3命名空间下的Pod信息:
[root@microservices-python]# kubectl get pods -o wide -n mp3 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES auth-57f6669cc8-4s6c8 1/1 Running 0 5m10s 10.244.0.246 vm1022 <none> <none> mongo-64696c8ccf-4n6sv 1/1 Running 0 28h 10.244.0.229 vm1022 <none> <none> mysql-6d878c4599-nvnj4 1/1 Running 0 5m28s 10.244.0.245 vm1022 <none> <none> rabbitmq-9d6fbf448-7gvr7 1/1 Running 0 27h 10.244.0.237 vm1022 <none> <none>
mp3命名空间下的Service信息:
[root@microservices-python]# kubectl get svc -n mp3 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE auth ClusterIP 10.111.255.31 <none> 5000/TCP 6m31s mongo ClusterIP 10.100.246.252 <none> 27017/TCP 28h mysql ClusterIP 10.100.218.240 <none> 3306/TCP 6m49s rabbitmq ClusterIP 10.110.92.100 <none> 15672/TCP,5672/TCP 27h
mysql Pod的Deployment定义:
apiVersion: apps/v1 kind: Deployment metadata: name: mysql namespace: mp3 spec: selector: matchLabels: app: mysql replicas: 1 template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:latest imagePullPolicy: Never envFrom: - configMapRef: name: mysql-configmap - secretRef: name: mysql-secret
mysql Service的定义:
apiVersion: v1 kind: Service metadata: name: mysql namespace: mp3 spec: type: ClusterIP selector: app: mysql ports: - name: http protocol: TCP port: 3306 targetPort: 3306
用于连接MySQL的Python代码:
from flask import Flask, request, make_response from flask_mysqldb import MySQL server = Flask(__name__) mysql = MySQL(server) # config server.config["MYSQL_HOST"] = 'mysql' server.config["MYSQL_USER"] = 'auth_user' server.config["MYSQL_PASSWORD"] = 'Auth123' server.config["MYSQL_DB"] = 'auth' server.config["MYSQL_PORT"] = 3306 @server.route("/login", methods=["POST"]) def login(): input_username = request.form.get("username") input_password = request.form.get("password") cur = mysql.connection.cursor() res = cur.execute( "SELECT email, password FROM user WHERE email=%s", (input_username,) )
出现的错误:
Traceback (most recent call last): File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 2073, in wsgi_app response = self.full_dispatch_request() File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1518, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1516, in full_dispatch_request rv = self.dispatch_request() File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1502, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args) File "/app/server.py", line 64, in login cur = mysql.connection.cursor() File "/usr/local/lib/python3.10/site-packages/flask_mysqldb/__init__.py", line 94, in connection ctx.mysql_db = self.connect File "/usr/local/lib/python3.10/site-packages/flask_mysqldb/__init__.py", line 81, in connect return MySQLdb.connect(**kwargs) File "/usr/local/lib/python3.10/site-packages/MySQLdb/__init__.py", line 123, in Connect return Connection(*args, **kwargs) File "/usr/local/lib/python3.10/site-packages/MySQLdb/connections.py", line 185, in __init__ super().__init__(*args, **kwargs2) MySQLdb._exceptions.OperationalError: (2002, "Can't connect to MySQL server on 'mysql' (110)")
请问故障原因是什么,以及应该如何排查该问题?
故障排查与解决方法
1. 验证Service与Pod的关联状态
首先确认mysql Service是否正确关联到mysql Pod:
- 执行命令查看Endpoints:
如果输出中kubectl get endpoints mysql -n mp3ENDPOINTS字段包含mysql Pod的IP(10.244.0.245:3306),说明Service和Pod关联正常;如果为空,检查Deployment的Pod标签是否和Service的selector匹配(当前配置中标签都是app:mysql,应该没问题,但需确认Pod是否处于就绪状态)。
2. 测试auth Pod到MySQL的网络连通性
进入auth Pod内部,直接测试网络:
- 进入auth Pod:
kubectl exec -it auth-57f6669cc8-4s6c8 -n mp3 -- sh - 解析mysql域名:
正常应该能解析到mysql Service的ClusterIP(ping mysql10.100.218.240),如果解析失败,检查集群DNS服务是否正常。 - 测试3306端口连通性:
如果连接失败,再直接测试mysql Pod的IP:nc -zv mysql 3306 # 或 telnet mysql 3306nc -zv 10.244.0.245 3306- 若Pod IP能连通:说明Service存在转发问题,检查Service的端口配置是否正确(当前port和targetPort都是3306,没问题)。
- 若Pod IP也不通:说明MySQL容器本身未监听3306端口,或存在网络策略限制。
3. 检查MySQL容器的绑定地址与用户权限
进入mysql Pod,检查MySQL的配置:
- 进入mysql Pod:
kubectl exec -it mysql-6d878c4599-nvnj4 -n mp3 -- sh - 登录MySQL(使用secret中的密码,需先解码secret:
kubectl get secret mysql-secret -n mp3 -o jsonpath='{.data.password}' | base64 -d):mysql -u root -p - 查看绑定地址:
如果结果是SHOW VARIABLES LIKE 'bind_address';127.0.0.1,MySQL仅允许本地访问,需要修改配置绑定0.0.0.0:- 在Deployment的容器env中添加环境变量:
- name: MYSQL_BIND_ADDRESS value: "0.0.0.0" - 或在configmap的my.cnf中配置
bind-address = 0.0.0.0
- 在Deployment的容器env中添加环境变量:
- 检查用户权限:
确保SELECT host, user FROM mysql.user;auth_user的host字段为%(允许任意IP访问)或auth Pod所在的网段(如10.244.0.0/16)。如果是localhost,执行授权命令:GRANT ALL PRIVILEGES ON auth.* TO 'auth_user'@'%' IDENTIFIED BY 'Auth123'; FLUSH PRIVILEGES;
4. 确认连接参数的正确性
检查代码中的配置与MySQL实际配置是否一致:
- 查看configmap中的数据库名:
确认是否包含kubectl get configmap mysql-configmap -n mp3 -o yamlMYSQL_DATABASE=auth。 - 查看secret中的密码:
确认解码后的密码是否为kubectl get secret mysql-secret -n mp3 -o jsonpath='{.data.password}' | base64 -dAuth123。
5. 检查集群网络策略
如果集群启用了NetworkPolicy,确认是否允许auth Pod访问mysql的3306端口:
- 查看当前命名空间的网络策略:
如果存在限制策略,需添加允许auth Pod标签访问mysql Pod标签的规则,例如:kubectl get networkpolicy -n mp3apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-auth-to-mysql namespace: mp3 spec: podSelector: matchLabels: app: mysql ingress: - from: - podSelector: matchLabels: app: auth # 替换为auth Pod的实际标签 ports: - protocol: TCP port: 3306
内容的提问来源于stack exchange,提问作者haojie
相关产品推荐
相关产品推荐

