【问题标题】:Contacting service in kubernetes在 Kubernetes 中联系服务
【发布时间】:2022-01-27 18:48:30
【问题描述】:

我以为我了解 kubernetes 服务的工作原理,并且一直将它们视为一种“分组”多个 pod 的方式,以使其能够联系服务而不是单个 pod。不过,好像我错了。我创建了一个 mysql 部署(只有一个 pod)和一个服务,以便在我想使用来自其他 pod(其他微服务)的 mysql 连接时访问该服务。这是我做的服务:

apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    run: mysql
spec:
  ports:
  - port: 3306
    targetPort: 3306
    protocol: TCP
  selector:
    run: mysql

我希望这可以让我通过到达<clusterIp>:<targetPort> 连接到 mysql pod,但是每当我尝试连接时连接都会被拒绝。我尝试在线阅读,最初认为nodeport 服务类型是个好主意,但 kubernetes 网站告诉<NodeIP>:<NodePort> 无法访问该服务,所以这让我感到困惑。 MySQL 应该只能在集群内部被其他节点访问。我怎样才能做到这一点?

注意事项:
  • 我正在开发 minikube。
  • 这是我尝试从一个 pod 连接到 python 上的 mysql 服务的方法:
service = api.read_namespaced_service(name="mysql", namespace="default")

mydb = mysql.connector.connect(host=service.spec.cluster_ip, user="root",
                                 password="password", database="db_name",
                                 auth_plugin='mysql_native_password')

这是我得到的错误:

Traceback (most recent call last):
  File "/init/db_init.py", line 10, in <module>
    mydb = mysql.connector.connect(host=service.spec.cluster_ip, user="root",
  File "/usr/local/lib/python3.9/site-packages/mysql/connector/__init__.py", line 272, in connect
    return CMySQLConnection(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/mysql/connector/connection_cext.py", line 85, in __init__
    self.connect(**kwargs)
  File "/usr/local/lib/python3.9/site-packages/mysql/connector/abstracts.py", line 1028, in connect
    self._open_connection()
  File "/usr/local/lib/python3.9/site-packages/mysql/connector/connection_cext.py", line 241, in _open_connection
    raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
mysql.connector.errors.DatabaseError: 2003 (HY000): Can't connect to MySQL server on '10.107.203.112:3306' (111)

更新

根据要求,这里是mysql pod的整个日志:

2022-01-27 17:57:14+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
2022-01-27 17:57:15+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2022-01-27 17:57:15+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
2022-01-27 17:57:15+00:00 [Note] [Entrypoint]: Initializing database files
2022-01-27T17:57:15.090697Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.28) initializing of server in progress as process 43
2022-01-27T17:57:15.105399Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-01-27T17:57:16.522380Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-01-27T17:57:20.805814Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
2022-01-27 17:57:29+00:00 [Note] [Entrypoint]: Database files initialized
2022-01-27 17:57:29+00:00 [Note] [Entrypoint]: Starting temporary server
2022-01-27T17:57:29.868217Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.28) starting as process 92
2022-01-27T17:57:29.892649Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-01-27T17:57:30.100941Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-01-27T17:57:30.398700Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2022-01-27T17:57:30.398743Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2022-01-27T17:57:30.419293Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2022-01-27T17:57:30.430833Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: /var/run/mysqld/mysqlx.sock
2022-01-27T17:57:30.430879Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.28'  socket: '/var/run/mysqld/mysqld.sock'  port: 0  MySQL Community Server - GPL.
2022-01-27 17:57:30+00:00 [Note] [Entrypoint]: Temporary server started.
Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
2022-01-27 17:57:32+00:00 [Note] [Entrypoint]: Creating database football

2022-01-27 17:57:32+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/SQL.sql


2022-01-27 17:57:33+00:00 [Note] [Entrypoint]: Stopping temporary server
2022-01-27T17:57:33.143178Z 12 [System] [MY-013172] [Server] Received SHUTDOWN from user root. Shutting down mysqld (Version: 8.0.28).
2022-01-27T17:57:36.222404Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.28)  MySQL Community Server - GPL.
2022-01-27 17:57:37+00:00 [Note] [Entrypoint]: Temporary server stopped

2022-01-27 17:57:37+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.

2022-01-27T17:57:37.329690Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.28) starting as process 1
2022-01-27T17:57:37.336444Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-01-27T17:57:37.525143Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-01-27T17:57:37.738175Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2022-01-27T17:57:37.738216Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2022-01-27T17:57:37.745722Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2022-01-27T17:57:37.757638Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
2022-01-27T17:57:37.757679Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.28'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.

另外,这是我使用的部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: repo/football-mysql
        name: mysql
        env:
          # Use secret in real usage
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim

【问题讨论】:

  • 这一行mysql.connector.errors.DatabaseError: 2003 (HY000): Can't connect to MySQL server on '10.107.203.112:3306' (111) 表明该服务在那里(它解析为一个IP)。您能否发布mysql pod 的日志以防出现问题?
  • 当然!我真的不知道怎么读,所以我把整个东西都贴出来了。非常感谢您的帮助@pkaramol!
  • @anemyte 是的。我正在使用部署更新帖子
  • @anemyte 抱歉,我对 kubernetes 很陌生,并不真正理解我做错了什么。我该如何解决这个问题?
  • 所以我将run 替换为app,对吧?

标签: python mysql kubernetes kubernetes-pod


【解决方案1】:

Service 和 Pod 之间的标签不匹配:

# service
spec:
  selector:
    run: mysql  # <- this

# deployment
spec:
  template:
    metadata:
      labels:
        app: mysql  # <- and this

因此,Service 以其他 Pod 为目标,而不是 Deployment 创建的 Pod。换句话说,Service 会查找 run 标签值等于 mysql 的 Pod,而您的 MySQL Pod 具有 app 标签,其中包含 mysql

要使其正常工作,Service 和 Pod 的两侧至少有一对标签必须完全相等。在这种情况下,将run 替换为app 就足够了:

apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    run: mysql  # changing here isn't mandatory, up to you
spec:
  ports:
  - port: 3306
    targetPort: 3306
    protocol: TCP
  selector:
    app: mysql  # here is the required change

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-06
    • 2021-06-09
    • 2015-12-31
    • 1970-01-01
    • 2016-05-18
    • 2019-10-02
    • 2019-04-18
    • 2016-01-27
    相关资源
    最近更新 更多