k8s集群内的pod连接集群外部的mysql, k8s集群内部服务如何连接集群外部mysql? 一文搞明白

ops/2025/2/27 3:54:11/

一、为什么不将mysql服务部署到k8s集群中使用呢?

1.有状态服务在K8s中的管理比较复杂,特别是持久化存储的问题。虽然K8s有StatefulSet和PV/PVC,但配置和维护起来需要更多工作,同时以下问题仍需解决:-存储可靠性:如果使用本地存储(如 hostPath),节点故障可能导致数据丢失;若用网络存储(如云盘),需确保性能和延迟满足数据库需求。 -备份与恢复:需额外配置定期备份工具(如 mysqldump、Percona XtraBackup),并验证恢复流程的可靠性。-数据库版本升级或迁移(如从 MySQL 5.7 到 8.0)在 Kubernetes 中可能涉及复杂的 StatefulSet 滚动更新策略,风险较高。2.网络和性能问题,比如存储I/O延迟,可能影响数据库性能。若应用和数据库部署在同一集群内,虽然网络延迟较低,但多副本数据库(如主从架构)跨节点通信可能引入额外延迟。高可用性和数据一致性也是挑战,需要配置主从复制、故障转移等。

二、什么情况下可以考虑在 Kubernetes 中部署 MySQL?

1.开发或测试环境快速迭代需求:在开发环境中,使用 Kubernetes 部署 MySQL 可以快速启停实例,配合 CI/CD 流水线实现自动化测试。
低成本验证架构:验证 Kubernetes 有状态服务管理能力时,可通过轻量级 MySQL 实例进行技术预研。2.本地化部署需求:在边缘节点(如工厂、物联网设备)中,若无法连接云端数据库,可在本地 Kubernetes 集群中部署 MySQL。
数据主权合规:某些行业要求数据必须存储在本地,此时需在私有 Kubernetes 集群中运行数据库。3.特殊版本或插件依赖:如果业务依赖特定 MySQL 版本或自定义插件(如自研的存储引擎),且云服务不兼容,可选择自建。
4.与 Kubernetes 生态深度集成:例如,需要将数据库日志直接接入集群内的 Elasticsearch,或通过 Service Mesh(如 Istio)实现数据库流量治理。

解决方案:在 Kubernetes 集群内部接入外部 MySQL 数据库,可以通过以下步骤实现。这里提供两种常见方法:使用 Service 资源直接指向外部地址通过 Endpoints 手动配置

实验开始前注意:

只要宿主机可以通讯,那么pod内也是可以直接通过宿主机的IP访问集群之外的服务。因为虽然是pod发出的请求,实际上经过转发,出去的时候是以宿主机的IP进行访问的,所以我们授权的时候,保证运行pod的宿主机能登录数据库就行了,并不是对pod的IP进行授权。

方法 1:使用 ExternalName 类型的 Service

适用于外部 MySQL 有固定域名的情况(如云服务商提供的数据库域名)。

1. 创建 ExternalName Service

[root@master ~]# mysql-external.yaml
apiVersion: v1
kind: Service
metadata:name: mysql-external  # 集群内通过该名称访问
spec:type: ExternalNameexternalName: your-mysql-hostname.example.com  # 外部MySQL的域名如:阿里云的RDSports:- port: 3306        # Service 暴露的端口targetPort: 3306  # 外部MySQL的实际端口

应用配置:

[root@master ~]# kubectl apply -f mysql-external.yaml
2. 应用程序连接方式

在应用中配置数据库主机为 mysql-external(Service 名称),端口为 3306。Kubernetes DNS 会自动将 mysql-external 解析为外部域名。

方法 2:手动指定 Endpoints(适用于IP直连)

如果外部 MySQL 是固定 IP 且无域名,可以手动创建 Service 和 Endpoints。

1.首先先登陆外部数据库创建一个普通用户并相应的授权设置为允许远程登陆。
[root@mysql-master ~]# mysql -uroot -p'Mysql@123!'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.44-log MySQL Community Server (GPL)Copyright (c) 2000, 2023, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> grant all on *.* to jack@'%' identified by 'Mysql@1233!';
Query OK, 0 rows affected, 1 warning (0.03 sec)mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)mysql>

在k8s集群中

1. 创建 Service 和 Endpoints

[root@master ~]# mkdir test/mysql -p 
[root@master ~]# cd test/mysql/
[root@master mysql]# kubectl create ns test #创建一个名称空间
[root@master mysql]# cat mysql-external-svc.yml
apiVersion: v1
kind: Service
metadata:name: mysql-externalnamespace: test
spec:ports:- port: 3306targetPort: 3306clusterIP: None #表示这是一个 headless service,直接通过 Endpoint 连接
---
apiVersion: v1
kind: Endpoints
metadata:namespace: testname: mysql-external #此名字需要于service中定义的name字段一致
subsets:
- addresses:- ip: 192.168.209.141 #定义外部mysql机器的ip地址ports:- port: 3306
当我们创建headless service时也会为service分配域名
service_name.namespace.svc.cluster.local我们可以通过dig或者nslookup 命令来解析查看dns是否解析成功。dns 为coredns负责解析

应用配置:

[root@master mysql]# kubectl apply -f mysql-external-svc.yml 
service/mysql-external created
endpoints/mysql-external created
[root@master mysql]# kubectl get svc,ep -n test 
NAME                     TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
service/mysql-external   ClusterIP   None         <none>        3306/TCP   4m16sNAME                       ENDPOINTS              AGE
endpoints/mysql-external   192.168.209.141:3306   4m16s
2. 应用程序连接方式

在代码中配置数据库主机为 mysql-external(Service名称),端口 3306


关键注意事项

1. 网络连通性
  • 确保集群节点能访问外部MySQL:检查防火墙、安全组是否放行 Kubernetes 节点到 MySQL 的 3306 端口。

  • 测试连接

    1.创建一个centos的pod
    [root@master mysql]# cat test-mysql.yml 
    apiVersion: v1
    kind: Pod
    metadata:name: centos7-podnamespace: test
    spec:nodeName: node-1containers:- name: centos7-containerimage: registry.cn-hangzhou.aliyuncs.com/testpm-k8s/centos:7command:- sleep- "3600"[root@master mysql]# kubectl get pod -n test
    NAME          READY   STATUS    RESTARTS   AGE
    centos7-pod   1/1     Running   0          7s[root@master mysql]# kubectl exec -it centos7-pod -n test -- /bin/bash
    [root@centos7-pod /]# yum install -y mysql
    [root@centos7-pod /]# mysql -ujack -p'Mysql@1233!' -h mysql-external
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 14
    Server version: 5.7.44-log MySQL Community Server (GPL)Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MySQL [(none)]> \q
    Bye在pod里面ping service的域名
    [root@centos7-pod /]# ping mysql-external
    PING mysql-external.test.svc.cluster.local (192.168.209.141) 56(84) bytes of data.
    64 bytes from 192-168-209-141.mysql-external.test.svc.cluster.local (192.168.209.141): icmp_seq=1 ttl=63 time=0.669 ms
    64 bytes from 192-168-209-141.mysql-external.test.svc.cluster.local (192.168.209.141): icmp_seq=2 ttl=63 time=1.06 ms
    

    通过ping service的域名可以看到返回的值为mysql宿主机的ip。

2. 数据库权限

确保 MySQL 用户允许从 Kubernetes Pod 的 IP 范围连接。例如:

CREATE USER 'jack'@'%' IDENTIFIED BY 'Mysql@1233!';
GRANT ALL PRIVILEGES ON *.* TO 'jack'@'%';

总结

  • 推荐方法:优先使用 ExternalName Service(有域名时)或手动配置 Endpoints(直接使用 IP)。
  • 调试工具:通过临时 Pod 执行 telnetmysql-client 命令验证连接。
  • 安全实践:始终通过 Secret 管理凭证,并启用 SSL 加密敏感数据传输。

通过以上步骤,Kubernetes 集群内的应用即可安全、稳定地访问外部 MySQL 数据库。


http://www.ppmy.cn/ops/161586.html

相关文章

给SQL server数据库表字段添加注释SQL,附修改、删除注释SQL及演示

目录 一. 前提小知识(数据库连接&#xff0c;数据库&#xff0c;SCHEMA&#xff0c;Table的关系) 二. 添加备注 2.1 添加备注基本语法(sys.sp_addextendedproperty) 2.2 SQL演示 2.3?fn_listextendedproperty函数查询备注个数 2.4 开发常用添加注释语法 三. 修改备注 …

【Windows系统node_modules删除失败(EPERM)问题解析与应对方案】

Windows系统node_modules删除失败(EPERM)问题解析与应对方案 问题现象 当开发者尝试删除Node.js项目的node_modules目录时&#xff0c;常会遇到如下错误提示&#xff1a; [Error: EPERM: operation not permitted, unlink D:\project\...\esbuild.exe] {errno: -4048,code: …

Solidity 开发环境

Solidity 开发环境 Solidity编辑器&#xff1a;Solidity编辑器是⼀种专⻔⽤于编写和编辑Solidity代码的编辑器。常⽤的Solidity编辑器包括 Visual Studio Code、Atom和Sublime Text。以太坊开发环境&#xff1a;以太坊开发环境&#xff08;Ethereum Development Environment&a…

爬虫运行后如何保存数据?

爬虫运行后&#xff0c;将获取到的数据保存到本地或数据库中是常见的需求。Python 提供了多种方式来保存数据&#xff0c;包括保存为文本文件、CSV 文件、JSON 文件&#xff0c;甚至存储到数据库中。以下是几种常见的数据保存方法&#xff0c;以及对应的代码示例。 1. 保存为文…

SOME/IP协议的建链过程

在SOME/IP协议中,建立服务通信链路的过程主要涉及服务发现机制,通常需要以下三次交互: 服务提供者广播服务可用性(Offer Service) 服务提供者启动后,周期性地通过Offer Service消息向网络广播其提供的服务实例信息(如Service ID、Instance ID、通信协议和端口等)。 作用…

谈谈 ES 6.8 到 7.10 的功能变迁(4)- 聚合功能篇

这一篇我们继续了解 ES 7.10 相较于 ES 6.8 新增的聚合方法。 Rare Terms 聚合 功能说明 用于聚合查询出字段中的稀有项。ES 常见的统计方法是使用 term 查询的正向排序&#xff0c;但是在大数据量和高基数的数据分布场景下会出现 unbounded 错误。Rare 聚合弥补了这个场景的…

【删边问题——Tarjan求割边】

题目 并查集暴力代码 30p #include <bits/stdc.h> using namespace std; using ll long long;const int N 1e510;int n, m; int a[N], p[N]; ll ans 1e18; ll s[3]; bool st;struct edge {int a, b; } e[N];void init() {for(int i 1; i < n; i)p[i] i; }int fi…

DeepSeek基础之机器学习

文章目录 一、核心概念总结&#xff08;一&#xff09;机器学习基本定义&#xff08;二&#xff09;基本术语&#xff08;三&#xff09;假设空间&#xff08;四&#xff09;归纳偏好&#xff08;五&#xff09;“没有免费的午餐”定理&#xff08;NFL 定理&#xff09; 二、重…