You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 mp3
    
    如果输出中ENDPOINTS字段包含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域名:
    ping mysql
    
    正常应该能解析到mysql Service的ClusterIP(10.100.218.240),如果解析失败,检查集群DNS服务是否正常。
  • 测试3306端口连通性:
    nc -zv mysql 3306
    # 或 telnet mysql 3306
    
    如果连接失败,再直接测试mysql Pod的IP:
    nc -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
  • 检查用户权限:
    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 yaml
    
    确认是否包含MYSQL_DATABASE=auth。
  • 查看secret中的密码:
    kubectl get secret mysql-secret -n mp3 -o jsonpath='{.data.password}' | base64 -d
    
    确认解码后的密码是否为Auth123。

5. 检查集群网络策略

如果集群启用了NetworkPolicy,确认是否允许auth Pod访问mysql的3306端口:

  • 查看当前命名空间的网络策略:
    kubectl get networkpolicy -n mp3
    
    如果存在限制策略,需添加允许auth Pod标签访问mysql Pod标签的规则,例如:
    apiVersion: 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 07:12:05