本博文是关于将 MinIO 租户服务暴露给 Amazon EKS 集群外部应用程序系列的第二部分。第一篇博文提供了四种方法的概述和比较,这些方法用于使用弹性负载均衡器在 AWS EKS 中暴露 MinIO 服务。
软件定义的 MinIO 为裸机和所有主要的 Kubernetes 平台(例如 Tanzu、Azure、GCP、OpenShift 和 SUSE Rancher)提供分布式高性能对象存储。MinIO 与 Amazon EKS 服务原生集成,使您能够利用最流行的云和世界上最快的对象存储。MinIO 是 AWS S3 的完整替代品,可以在 EKS 以及本地和/或其他云上运行。客户使用 MinIO 用于各种用途,例如提供多租户对象存储即服务、多应用程序数据湖仓或 AI/ML 处理管道。
为了最大限度地利用 EKS 上的 MinIO,您需要将其 Kubernetes 服务(UI 和 API)暴露给集群外部的用户和应用程序,无论是内部到 AWS 使用虚拟私有云 (VPC) 还是外部到互联网。
本博文将引导您完成三个选项:经典负载均衡器、应用程序负载均衡器和网络负载均衡器。我们将向您展示如何在 EKS 上部署它们,包括架构讨论以及此方法的优缺点。
使用经典负载均衡器暴露 MinIO 服务
要在 EKS 上使用经典负载均衡器暴露服务,您只需将服务 type: LoadBalancer
;为此,租户 CRD 具有 exposeServices 属性,该属性告诉 Operator 代表您处理服务的创建。
首先,我们需要一个 EKS 集群、一个 MinIO Operator 和一个 MinIO 租户。请按照 通过 EKS 部署 MinIO 中的说明操作。
然后在租户清单中,我们像下面的示例一样指定 exposeServices 中的字段
apiVersion: minio.min.io/v2 kind: Tenant metadata: name: minio-tenant-1 namespace: minio-tenant-1 Spec: ... exposeServices: console: true minio: true ... |
这将把控制台和 MinIO 服务类型设置为 LoadBalancer
,然后 EKS 将创建 2 个经典负载均衡器,一个用于 MinIO 控制台 服务,另一个用于 MinIO 服务器 服务,如下面的图像所示。

现在,您可以通过端口 9443(HTTPS)浏览 MinIO 控制台。

并通过端口 443(HTTPS)访问 MinIO API。
~ curl -k https://a380f6d1bc70241c981c0f6a6fa324cf-1463137531.us-east-1.elb.amazonaws.com <?xml version="1.0" encoding="UTF-8"?> <Error><Code>AccessDenied</Code><Message>Access Denied.</Message><Resource>/</Resource><RequestId>171FE8F42987C613</RequestId><HostId>3cb3ba23-1285-4269-8f8a-678ce127d532</HostId></Error> |
流量转发
EKS 为我们创建负载均衡器,并为服务公开的每个端口添加一个监听器。在 MinIO 服务的情况下,EKS 在端口 443 上添加了一个监听器,如下面的图像所示。

监听器将流量转发到集群中每个实例(也称为节点)上的同一端口。

服务以 NodePort 的形式公开,使用 Kubernetes 中运行的所有节点的端口 N;在前面的示例中,此端口将为 30144。

Kubernetes NodePort 将接收到的流量转发到服务 MinIO,然后服务将流量转发到与服务过滤器匹配的 Pod。
经典负载均衡器创建 TCP(第 4 层)监听器,并且不筛选任何流量。

如果您使用 TLS,则 MinIO 服务本身负责 TLS 终止。请参阅 网络加密 TLS 文档,以了解有关如何在 MinIO 中配置 TLS 证书的更多信息。
使用经典负载均衡器公开 Operator 控制台
要允许从 Kubernetes 集群外部使用经典负载均衡器访问 MinIO Operator 控制台,只需将服务类型从 ClusterIP 更改为 LoadBalancer 即可。例如
kubectl get service console -n minio-operator -oyaml > console.yaml |
文件内容将类似于以下内容
apiVersion: v1 kind: Service metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"operator.min.io/authors":"MinIO, Inc.","operator.min.io/license":"AGPLv3","operator$ operator.min.io/authors: MinIO, Inc. operator.min.io/license: AGPLv3 operator.min.io/support: https://subnet.min.io creationTimestamp: "2022-10-20T21:33:09Z" labels: name: console name: console namespace: minio-operator resourceVersion: "19562" uid: d824df76-48d7-4e20-9bb9-60970b55be5a spec: clusterIP: 10.100.42.174 clusterIPs: - 10.100.42.174 internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - name: http port: 9090 protocol: TCP targetPort: 9090 - name: https port: 9443 protocol: TCP targetPort: 9443 selector: app: console sessionAffinity: None type: ClusterIP status: loadBalancer: {} |
我们只需要将 type 字段从 ClusterIP
更改为 LoadBalancer
。
apiVersion: v1 kind: Service spec: ... type: LoadBalancer ... |
然后应用更改
kubectl apply -f console.yaml service/console configured |
您将在 AWS EC2 控制台中看到一个新的负载均衡器。

还可以从服务的 status 中获取负载均衡器的 DNS 主机名。
kubectl get service console -n minio-operator -o jsonpath="{.status.loadBalancer.ingress[0].hostname}" ad824df7648d74e209bb960970b55be5-230115377.us-east-1.elb.amazonaws.com |
最后,要管理 MinIO,请通过浏览器访问列出的主机名上的端口 9090 处的 MinIO Operator 控制台。

经典负载均衡器的其他服务注解
虽然经典负载均衡器是 AWS EKS 上的默认负载均衡器,但有时我们需要自定义其行为。这可以通过向 MinIO 服务和 MinIO 控制台服务以及 MinIO Operator 控制台服务添加注解来实现。
Kubernetes 服务文档列出了经典负载均衡器支持的所有注解。
MinIO 租户控制台和 MinIO 服务注解
要向 MinIO 控制台和 MinIO 服务添加注解,我们在租户清单中的serviceMetadata 字段中添加它们。
示例:经典负载均衡器内部
在此示例中,我们将使用如下注解配置 MinIO 服务和 MinIO 控制台的经典负载均衡器类型为内部,以允许内部流量。
apiVersion: minio.min.io/v2 kind: Tenant metadata: name: minio-tenant spec: ... serviceMetadata: consoleServiceAnnotations: service.beta.kubernetes.io/aws-load-balancer-internal: "true" minioServiceAnnotations: service.beta.kubernetes.io/aws-load-balancer-internal: "true" ... |
Operator 控制台服务注解
要公开 Operator 控制台服务,我们需要直接对其应用注解。
示例:经典负载均衡器上的 TLS 终止

添加以下注解将在经典负载均衡器上启用 TLS 终止,并在端口 9090 上使用 AWS ACM 发行的证书,并将后端流量作为未加密的 HTTP 发送。
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:regn:acct:certificate/id service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "9090" |
为了实现这一点,让我们首先列出 Operator 控制台服务的清单。
kubectl get service -n minio-operator console -oyaml operator-console.yaml |
编辑注解后,Operator 控制台服务的清单将如下所示
apiVersion: v1 kind: Service metadata: annotations: ... service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:111111111111:certificate/3493eeee-850a-4010-afcf-225fb0f2a2b4 service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "9090" ... name: console namespace: minio-operator spec: ... type: LoadBalancer |
注意:为了强调重要部分并节省空间,清单中的某些部分已编辑并替换为省略号。
编辑完成后,应用更改
kubectl apply -f operator-console.yaml service/console 配置完成 |
经典负载均衡器的监听器公开端口 9090,并为该端口分配证书,如下所示。

现在,我们可以使用具有有效公共 TLS 证书的 HTTPS 导航到 Operator 控制台 UI。

经典负载均衡器注解
以下是 MinIO 服务中一些最常用的注解。
内部经典负载均衡器
此注解将使负载均衡器仅限于内部使用,而不是默认的公网访问。
service.beta.kubernetes.io/aws-load-balancer-internal: "true" |
更改密码和 TLS 协议
此注解将更改 TLS 策略。当您需要某个特定的密码组或 SSL 协议(例如 TLS 1、TLS 1.1 或 TLS 1.2)时,请使用它。(此处是经典负载均衡器策略组列表)。
service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: "ELBSecurityPolicy-TLS-1-2-2017-01" |
启用经典负载均衡器访问日志
service.beta.kubernetes.io/aws-load-balancer-access-log-enabled: "true" service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval: "60" service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name: "my-bucket" service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix: "my-bucket-prefix/prod" |
这些注解共同使您能够将 ELB 注解存储到 S3 目标中。访问日志有助于识别连接问题,以及按请求细化的请求详细信息,请参阅 AWS 文档中如何解释访问日志。
确保目标 S3 和 ELB 位于同一个 AWS 区域,并且 S3 存储桶已启用来自 ELB 的写入访问日志。
经典负载均衡器的安全组
有时需要针对与负载均衡器关联的安全组进行自定义安全设置,特别是在手动或使用特定安全措施创建 Kubernetes 集群时,以下 2 个注释将在此类情况下提供帮助。
service.beta.kubernetes.io/aws-load-balancer-security-groups: "sg-53fae93f" |
要配置在创建的 ELB 上的现有安全组列表。与注释service.beta.kubernetes.io/aws-load-balancer-extra-security-groups
不同,这将替换之前分配给 ELB 的所有其他安全组,并覆盖为此 ELB 创建唯一生成的安全组。
此列表中的第一个安全组 ID 用作允许传入流量到目标工作节点(服务流量和健康检查)的源。
如果多个 ELB 配置了相同的安全组 ID,则只会向工作节点安全组添加一行允许规则,这意味着如果删除任何这些 ELB,它将删除该允许规则并阻止所有共享相同安全组 ID 的 ELB 的访问。
如果使用不当,这可能会导致跨服务中断。
service.beta.kubernetes.io/aws-load-balancer-extra-security-groups: "sg-53fae93f,sg-42efd82e" |
要添加到创建的 ELB 的其他安全组列表。
经典负载均衡器跨可用区负载均衡
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" |
跨可用区负载均衡 将流量均匀地分布到所有可用区中的所有后端实例。
经典负载均衡器中的端到端 TLS 加密

service.beta.kubernetes.io/aws-load-balancer-ssl-cert: certificate-arn |
尽管可以使用service.beta.kubernetes.io/aws-load-balancer-ssl-cert
注释将 AWS ACM 发行的证书分配给经典负载均衡器以在负载均衡器中执行 TLS 终止,但为了使经典负载均衡器信任后端服务(MinIO),它需要该服务在 Pod 的 HTTPS 端口上使用有效的公共 CA 发行的证书,或者将 MinIO 提供服务的 Kubernetes 发行的证书上传到负载均衡器作为“后端证书”以信任它。
目前,在 EKS 中通过注释从 Kubernetes 内部执行此操作尚无自动化方式。相反,您可以使用 AWS 控制台 UI 创建和配置经典负载均衡器的创建,如下所示。

即使我们将 MinIO 服务证书添加到负载均衡器,对负载均衡器配置的任何手动更改都可能(并且很可能)在 MinIO 运算符的下一个协调循环期间丢失。因此,**不建议在 MinIO 具有自签名证书或私有 CA 发行证书时在经典负载均衡器上执行 TLS 终止**。相反,请为此目的使用 Nginx Ingress、应用程序负载均衡器或网络负载均衡器等替代方案。
使用应用程序负载均衡器公开 MinIO 租户服务
应用程序负载均衡器在 OSI 模型的应用程序层或第七层工作。监听器配置为根据应用程序流量的内容将请求路由到不同的目标组。应用程序负载均衡器 提供了比经典负载均衡器更多的关键增强功能,包括支持将 Lambda 函数注册为目标,以及更大的自定义和改进的性能。
首先,我们需要一个 EKS 集群,安装 MinIO 运算符和一个租户,请按照通过 EKS 部署 MinIO中的说明进行操作。
在 EKS 集群上,我们需要安装 AWS 负载均衡器控制器,请参阅此处的说明。
然后,我们将使用正确的 ALB 注释创建一个 Ingress 清单,请参阅此处的完整注释列表。
示例:应用程序负载均衡器端到端 TLS 加密

请注意以下有关此示例的信息
- 创建了一个单一的 ALB,在端口 443 上侦听。
- 两个域名tenant.exampledomain.com和minio.exampledomain.com的 DNS 都将指向同一个 ALB,使用主机名解析,ALB 入站将流量分别转发到正确的服务console或minio。
- 200 和 443 是健康检查的有效成功代码。
- 使用 ACM 托管的 SSL 证书在 ALB 级别终止面向公众域名的 TLS(tenant-console.exampledomain.com和minio.exampledomain.com)。
- 来自应用程序负载均衡器到服务的流量是 TLS 加密的,即使证书无效(自签名证书或私有 CA 发行证书)。
编辑下面示例 Ingress 清单中标有#replace注释的字段,以匹配您的环境所需的设置。
#tenant-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tenant-ingress #replace namespace: tenant-namespace #replace annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/certificate-arn: Certificate ARN #replace # alb.ingress.kubernetes.io/subnets: subnet-a, subnet-b, subnet-c, subnet-d #replace alb.ingress.kubernetes.io/backend-protocol: HTTPS alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/healthcheck-protocol: HTTPS alb.ingress.kubernetes.io/success-codes: '200,403' spec: ingressClassName: alb rules: - host: tenant-console.exampledomain.com #replace http: paths: - path: / pathType: Prefix backend: service: name: tenant-namespace-console #replace tenant-namespace port: number: 9443 - host: minio.exampledomain.com #replace http: paths: - path: / pathType: Prefix backend: service: name: minio port: number: 443 |
最后,应用清单。
kubectl apply -f tenant-ingress.yaml ingress/tenant-ingress configured |
ALB 的一个特点是它们不会根据此 AWS 文档验证后端 TLS 证书。
“...您可以使用自签名证书或已过期的证书。因为负载均衡器位于虚拟私有云 (VPC) 中,所以负载均衡器和目标之间的流量在数据包级别进行身份验证,因此即使目标上的证书无效,也不存在中间人攻击或欺骗的风险。”
这意味着您可以在 ALB 上使用有效的 TLS 证书进行 TLS 终止,然后在 MinIO 服务中使用自签名证书、kubernetes CA 发行证书或任何其他私有 CA 发行证书来启用端到端加密。
使用应用程序负载均衡器公开 MinIO 运算符控制台
使用 ALB 入站公开运算符控制台的方式与公开租户和控制台的方式类似,即通过创建入站。
示例:在 ALB 中使用 TLS 终止的运算符控制台

在此示例中,我们将
- 将使用主机标头operator.exampledomain.com接收的流量路由到运算符控制台服务(将自定义域替换为您自己的域)。
- 在 ALB 上设置 TLS 终止。
- 将 HTTP 流量转发到端口 9090,运算符控制台在该端口上公开。
编辑下面示例 Ingress 清单中标有#replace注释的字段,以匹配您的设置。
#operator-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: operator-ingress namespace: minio-operator annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/certificate-arn: Certificate ARN #replace # alb.ingress.kubernetes.io/subnets: subnet-a, subnet-b #replace alb.ingress.kubernetes.io/backend-protocol: HTTP alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/healthcheck-protocol: HTTP alb.ingress.kubernetes.io/success-codes: '200' spec: ingressClassName: alb rules: - host: operator.exampledomain.com #replace http: paths: - path: / pathType: Prefix backend: service: name: console port: number: 9090 |
然后,应用清单。
kubectl apply -f operator-ingress.yaml ingress/operator-ingress configured |
使用网络负载均衡器公开 MinIO 租户服务
公开 EKS 集群外部的 MinIO 的最终选项是使用网络负载均衡器。
像往常一样,我们将首先创建一个 EKS 集群,安装 MinIO 运算符和一个租户。您可以按照通过 EKS 部署 MinIO中的说明进行操作。
在 EKS 集群上,我们还需要安装 AWS 负载均衡器控制器,请参阅此处的说明。
示例:使用网络负载均衡器公开 MinIO 服务和 MinIO 运算符控制台服务
我们将再次编辑租户清单以指定exposeServices,并且我们将设置注释以指定我们想要网络负载均衡器,否则 Kubernetes 将改为预配默认的经典负载均衡器。
在serviceMetada字段中,我们为 MinIO 运算符控制台和 MinIO 服务指定注释,例如
apiVersion: minio.min.io/v2 kind: Tenant metadata: name: minio-tenant-1 namespace: minio-tenant-1 Spec: ... exposeServices: console: true minio: true ... serviceMetadata: consoleServiceAnnotations: service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-type: external minioServiceAnnotations: service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-type: external |
这将为 MinIO 服务创建一个网络负载均衡器,并为 MinIO Operator 控制台服务创建另一个网络负载均衡器。
网络负载均衡器将在端口 443 上添加一个 TCP 监听器以供 MinIO 使用,如下所示。

网络负载均衡器侦听 TCP(第 4 层)流量。因此,网络负载均衡器不会过滤任何流量。

MinIO 服务本身将负责 TLS 终止。如果这是您想要执行的操作,请参阅 网络加密 TLS 文档,以了解有关在 MinIO 中配置 TLS 证书的更多信息。
对于MinIO Operator 控制台服务,让我们在端口 9443 上添加一个 TCP 监听器,如下所示。


如果您希望MinIO Operator 控制台服务本身负责 TLS 终止,请参阅 网络加密 TLS 文档,以了解如何在 MinIO 中配置 TLS 证书。
示例:使用 TLS 终止公开 MinIO Operator 控制台

添加以下注释将在网络负载均衡器上设置 TLS 终止,使用 AWS ACM 发行的证书,在端口 9090 上,并将后端流量作为未加密的 HTTP 流量发送。
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-type: external service.beta.kubernetes.io/aws-load-balancer-backend-protocol:tcp service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:regn:acct:certificate/id service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "9090" |
让我们回到服务清单。在此示例中,我们将使用 MinIO Operator 控制台服务。
kubectl get service -n minio-operator console -oyaml > operator-console.yaml |
然后,添加注释并将类型更改为LoadBalancer
。生成的 MinIO Operator 控制台服务描述符将如下所示
apiVersion: v1 kind: Service metadata: annotations: ... service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-type: external service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:111111111111:certificate/3493eeee-850a-4010-afcf-225fb0f2a2b4 service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "9090" ... name: console namespace: minio-operator spec: ... type: LoadBalancer ... |
注意:清单的某些部分已编辑并替换为省略号,以缩短文件并强调相关部分。
接下来,应用清单。
kubectl apply -f operator-console.yaml service/console 配置完成 |
网络负载均衡器的监听器公开端口 9090 并将证书分配给该端口,如下所示。

接下来,使用浏览器导航到 MinIO Operator 控制台,使用带有有效公共 TLS 证书的 HTTPS。

网络负载均衡器的其他服务注释
下面您将找到一些使用网络负载均衡器注释的最常见配置。有关 AWS 网络负载均衡器服务注释的完整参考,请查阅 AWS 负载均衡器控制器文档。
网络负载均衡器注释
面向互联网的网络负载均衡器
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" |
此注释将使网络负载均衡器连接到互联网,而不是默认的内部网络。
子网
service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-xxxx, mySubnet |
使用此注释指定要与网络负载均衡器关联的子网列表。
访问日志
service.beta.kubernetes.io/aws-load-balancer-attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=my-access-log-bucket,access_logs.s3.prefix=my-app |
使用aws-load-balancer-attributes注释配置网络负载均衡器的访问日志。
目标类型
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance |
此注释指定要为网络负载均衡器配置的目标类型。您可以在**instance**和**IP**之间进行选择。
请参阅EKS最佳实践网络文档,以详细了解不同的方法和用例。
实例M模式
这是在 Kubernetes 上公开服务的默认和最常见模式,它将流量路由到集群中所有 EC2 实例上为您的服务打开的 NodePort。

在上面的示例中,所有三个节点都添加到目标组中。

NLB 将流量路由到所有节点,包括 IP 为 172.0.0.3 的节点,即使该节点上没有运行服务的 Pod。各个工作节点上的 Kube-proxy 设置了从 NodePort 到服务后端 Pod 的流量转发。
IP 模式
此模式将流量直接路由到 Pod IP。AWS NLB 将流量直接发送到服务后端的 Kubernetes Pod,无需通过 Kubernetes 集群中的工作节点进行额外的网络跳跃。

由于 Pod 具有一个 ENI 和一个可在 VPC 中访问的 IP 地址,因此网络负载均衡器无需通过 kube-proxy 路由流量,只需路由到目标组的 pod-id:port 组合,不包括未运行服务 Pod 的节点 IP。

此模式需要在 EKS 集群上安装AWS VPC CNI 插件。
此网络的一些用例(除其他外)包括
- 减少通过 kube-proxy 跳跃的延迟
- IPv6 支持
- 每个 Pod 的安全组
- 自定义网络
IPv6
service.beta.kubernetes.io/aws-load-balancer-type: "external" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip" service.beta.kubernetes.io/aws-load-balancer-ip-address-type: dualstack |
如果您正在将负载均衡到 IPv6 Pod,请添加service.beta.kubernetes.io/aws-load-balancer-ip-address-type: dualstack
注释。您只能将负载均衡到 IPv6 的 IP 目标,而不是实例目标。没有此注释,负载均衡将通过 IPv4 进行。
使用 MinIO 和托管 Kubernetes 实现神奇效果
这篇博文提供了详细的说明,介绍如何将 MinIO 运营商控制台和租户服务公开给 Kubernetes 集群外部的应用程序和用户。无论您是在 EKS 还是其他 Kubernetes 发行版上运行,托管或非托管,部署和管理 Kubernetes 原生 MinIO 都非常简单。
试用AWS 市场上的 MinIO 托管应用程序或下载 MinIO并立即在本地部署它。