暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【译】使用 Ingress 在 Kubernetes 上公开数据库

原创 热血青年 2022-06-22
2166

原文链接:https://www.percona.com/blog/expose-databases-on-kubernetes-with-ingress
作者:Sergey Pronin

Ingress 是一种资源,通常用于在 Kubernetes 之外公开 HTTP(s) 服务。要获得入口支持,您将需要一个入口控制器,简而言之就是一个代理。 SRE 和 DevOps 喜欢 ingress,因为它为开发人员提供了一种自助服务来公开他们的应用程序。开发人员喜欢它,因为它使用简单,但同时又非常灵活。

高级入口设计如下所示:
1.png

1、用户通过单个负载均衡器或其他 Kubernetes 服务进行连接

2、流量通过 Ingress Pod(或 Pod 以实现高可用性)进行路由。
入口控制器有多种风格。有些使用 nginx、一些 envoy 或其他代理。在此处查看 Ingress Controller 的精选列表。

3、基于 HTTP 标头,流量被路由到运行网站的相应 Pod。对于 HTTPS 流量,使用服务器名称指示 (SNI),这是大多数浏览器支持的 TLS 扩展。通常,入口控制器与 cert-manager 很好地集成,它为您提供完整的 TLS 生命周期支持(是的,不再需要担心续订)。

这种设计的美妙之处和价值在于您有一个负载均衡器为您的所有网站提供服务。在公共云中,它可以节省成本,而在私有云中,它可以简化您的网络或减少 IPv4 地址的数量(如果您还没有使用 IPv6)。

带有入口的 TCP 和 UDP

非常有趣的是,一些入口控制器还支持 TCP 和 UDP 代理。在我们的论坛和 Kubernetes slack 上,我多次被问到是否可以将 ingress 与 Percona Operators 一起使用。嗯,是的。通常,每个数据库集群都需要一个负载均衡器:
2.png
带有入口的设计会稍微复杂一些,但仍然允许您将单个负载均衡器用于多个数据库。在您运行数百个集群的情况下,它可以显著地节省成本。

3.png

1、每个 TCP 端口代表数据库集群

2、入口控制器根据端口决定将流量路由到哪里

这种设计的明显缺点是数据库的非默认 TCP 端口。可能会出现一些奇怪的情况,它可以变成一个阻止程序,但通常情况下,它不应该。

动手操作

我的目标是拥有以下内容:

  • Kubernetes 1.21(我将使用 civo.com,但它应该适用于任何其他托管或私有 k8s)
  • 通过 ingress-nginx 暴露 Percona Operator for MySQL 管理的三个 MySQL 集群
    每个集群在一个单独的端口上

我在这篇博文中使用的所有配置文件都可以在这个 Github 存储库中找到。

部署 Percona XtraDB 集群 (PXC)

kubectl apply -f https://raw.githubusercontent.com/spron-in/blog-data/master/operators-and-ingress/bundle.yaml
kubectl apply -f https://raw.githubusercontent.com/spron-in/blog-data/master/operators-and-ingress/cr-minimal.yaml
kubectl apply -f https://raw.githubusercontent.com/spron-in/blog-data/master/operators-and-ingress/cr-minimal2.yaml
kubectl apply -f https://raw.githubusercontent.com/spron-in/blog-data/master/operators-and-ingress/cr-minimal3.yaml

部署入口

helm upgrade --install ingress-nginx ingress-nginx   --repo https://kubernetes.github.io/ingress-nginx   --namespace ingress-nginx --create-namespace  \
--set controller.replicaCount=2 \
--set tcp.3306="default/minimal-cluster-haproxy:3306"  \
--set tcp.3307="default/minimal-cluster2-haproxy:3306" \
--set tcp.3308="default/minimal-cluster3-haproxy:3306"

这将部署一个高可用的 ingress-nginx 控制器。

1、controller.replicaCount=2 - 定义我们希望至少有两个入口控制器 Pod。这是为了提供高度可用的设置。

2、tcp 标志做两件事:

  • 在入口的负载均衡器上公开端口 3306-3308
  • 指示入口控制器将流量转发到由 Percona Operator 为 PXC 集群创建的相应服务。例如,端口 3307 是用于连接到最小集群 2 的端口。在入口文档中阅读有关此配置的更多信息。

这是创建的负载均衡器资源:

$ kubectl -n ingress-nginx get service
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)                                                                   AGE
…
ingress-nginx-controller             LoadBalancer   10.43.72.142    212.2.244.54   80:30261/TCP,443:32112/TCP,3306:31583/TCP,3307:30786/TCP,3308:31827/TCP   4m13s

如您所见,端口 3306-3308 已暴露。

检查连接

就是这个。数据库集群应该是公开且可访问的。让我们检查一下连接。

获取 minimum-cluster2 的 root 密码:

$ kubectl get secrets minimal-cluster2-secrets | grep root | awk '{print $2}' | base64 --decode && echo
kSNzx3putYecHwSXEgf

连接到数据库:

$ mysql -u root -h 212.2.244.54 --port 3307  -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5722

有用!请注意我如何使用端口 3307,它对应于最小集群 2。

添加更多集群

如果您在图片中添加更多集群怎么办,您如何公开这些集群?

Helm

如果您使用 helm,最简单的方法是在命令中再添加一个标志:

helm upgrade --install ingress-nginx ingress-nginx   --repo https://kubernetes.github.io/ingress-nginx   --namespace ingress-nginx --create-namespace  \
--set controller.replicaCount=2 \
--set tcp.3306="default/minimal-cluster-haproxy:3306"  \
--set tcp.3307="default/minimal-cluster2-haproxy:3306" \
--set tcp.3308="default/minimal-cluster3-haproxy:3306" \
--set tcp.3309="default/minimal-cluster4-haproxy:3306"

没有Helm

如果没有 Helm,这是一个两步过程:

首先,编辑配置 TCP 服务公开的 configMap。默认情况下,它被称为 ingress-nginx-tcp

kubectl -n ingress-nginx edit cm ingress-nginx-tcp
…
apiVersion: v1
data:
  "3306": default/minimal-cluster-haproxy:3306
  "3307": default/minimal-cluster2-haproxy:3306
  "3308": default/minimal-cluster3-haproxy:3306
  "3309": default/minimal-cluster4-haproxy:3306

configMap 中的更改将触发 ingress pod 中 nginx 的重新配置。但作为第二步,还需要在负载均衡器上公开此端口。为此 – 编辑相应的服务:

kubectl -n ingress-nginx edit services ingress-nginx-controller
…
spec:
  ports:
    …
  - name: 3309-tcp
    port: 3309
    protocol: TCP
    targetPort: 3309-tcp

新集群现在暴露在端口 3309 上。

限制和注意事项

每个负载均衡器的端口

云提供商通常会限制您可以通过单个负载均衡器公开的端口数量:

  • AWS 每个 NLB 有 50 个侦听器,GCP 每个服务有 100 个端口。

如果达到限制,只需创建另一个指向入口控制器的负载均衡器。

自动化

节省成本是件好事,但有了 Kubernetes 的能力,用户希望避免手动任务,而不是添加更多。将 ingress configMap 和负载均衡器端口的变化集成到 CICD 中并不是一项艰巨的任务,但维护添加新负载均衡器以添加更多端口的逻辑更难。目前我还没有找到任何实现重用负载均衡器端口或以任何方式自动化它的逻辑的项目。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论