使用 Ingress NGINX 和 NLB 优化 EKS 中多个 Kubernetes 服务的外部和内部访问

要提供对 Amazon EKS 集群中多个 Kubernetes 服务的外部访问,您可以使用 Ingress NGINX 控制器或适用于 Kubernetes 的 AWS 负载均衡器控制器。

  • 配置公共和私有负载均衡器:我将向您展示如何使用 Ingress 控制器设置公共和私有负载均衡器。这样,您可以将私有负载均衡器用于网络内的内部流量,将公共负载均衡器用于来自外部的流量。
  • 使用多个 Ingress 文件路由流量:我将解释如何使用不同的 Ingress 文件将流量定向到不同的 Kubernetes 服务。如果您对不同类型的流量设置了不同的规则,这将非常有用。
  • 使用单个 Ingress 文件路由流量:我还将介绍如何使用单个 Ingress 文件管理流向各种 Kubernetes 服务的流量。此方法可帮助您将路由规则整合到单个配置中。


在深入探讨这些场景之前,让我们先了解一下什么是 Ingress NGINX 控制器以及如何设置它。

Ingress NGINX 控制器


Ingress NGINX 控制器充当 Kubernetes 服务的网关。它管理进入 Kubernetes 集群的流量,并根据您定义的规则将其定向到正确的服务。您可以将其视为流量引导器,确保请求顺利到达正确的目的地。

“Ingress”和“Ingress 控制器”之间存在差异:

Ingress 是一种 Kubernetes 资源,用于管理从集群外部到集群内部服务的 HTTP 和 HTTPS 流量。
Ingress 控制器是实现此功能的工具,通常使用负载均衡器。没有 Ingress 控制器,您就无法使用 Ingress。
IngressClass 可以帮助您选择要使用的 Ingress 控制器。


如何安装 Ingress NGINX 控制器


有几种简单的方法可以安装 Ingress NGINX。以下是每种方法的简单指南:

1. 使用 Helm:

a) 添加 Ingress NGINX Helm 仓库:这就像从专门的商店获取所需的工具一样。

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

 b) 为 Ingress NGINX 创建一个命名空间:这将设置一个 Ingress NGINX 可以工作的空间。

$ kubectl create namespace ingress-nginx

c) 安装 Ingress NGINX:这将把 Ingress NGINX 放入您的 Kubernetes 环境中。

helm install my-ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx

2. 使用 YAML 文件:

下载 deploy.yaml 文件并应用。

这将使用预定义文件设置 Ingress NGINX。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.1/deploy/static/provider/cloud/deploy.yaml

这将安装 Ingress NGINX 。

注意:这将在 AWS 中创建经典负载均衡器,我们可以使用不同类型的 Kubernetes 服务(ClusterIP、NodePort 或 LoadBalancer)来公开 Ingress Nginx Controller 服务。

使用 Ingress NGINX 控制器配置公有和私有网络负载均衡器


先决条件:安装 AWS 负载均衡器控制器。最佳实践是使用 AWS 负载均衡器控制器为 Amazon EKS 中的 LoadBalancer 类型服务对象创建和管理网络负载均衡器。

在 EKS 集群中配置 AWS 负载均衡器控制器后,您可以验证其状态。

$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
aws-load-balancer-controller-b59f12345-j9cw 1/1 Running 0 1d
aws-load-balancer-controller-b59f77777-xdh2 1/1 Running 0 1d

在 AWS 中,我们使用网络负载均衡器 (NLB) 将 Ingress-Nginx 控制器暴露在 Type=LoadBalancer 的服务后面。

要使用 Ingress NGINX 控制器设置私有和公共负载均衡器,请先下载 deploy.yaml 文件。然后,您可以根据需要自定义此文件来配置负载均衡器。

ninjamac@ninjamacdeMacBook-Air eks % curl -O https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.1/deploy/static/provider/aws/deploy.yaml     
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 16407  100 16407    0     0  18449      0 --:--:-- --:--:-- --:--:-- 18434

 注释掉 NLB 的当前服务详情,添加提供的新行,然后应用更新后的文件。

注意:请务必更新 VPC 子网的标签。

---
apiVersion: v1
kind: Service
metadata:
  annotations:
    # Create External NLB
    service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/aws-load-balancer-manage-backend-security-group-rules: "true"
    service.beta.kubernetes.io/aws-load-balancer-security-groups: "sg-XXXXXX"
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:ap-south-1:XXXXXX:certificate/XXXXXXX
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "ssl"
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
    service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600'
    service.beta.kubernetes.io/aws-load-balancer-name: "ingress-nginx-external-nlb"
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.11.1
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  externalTrafficPolicy: Local
  ports:
  - appProtocol: http
    name: http
    port: 80
    protocol: TCP
    targetPort: http
  - appProtocol: https
    name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    # Create internal NLB
    service.beta.kubernetes.io/aws-load-balancer-scheme: "internal"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/aws-load-balancer-manage-backend-security-group-rules: "true"
    service.beta.kubernetes.io/aws-load-balancer-security-groups: "sg-XXXXXXXX"
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:ap-south-1:XXXXXX:certificate/XXXXXXXXX
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "ssl"
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
    service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600'
    service.beta.kubernetes.io/aws-load-balancer-name: "ingress-nginx-internal-nlb"
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.11.1
  name: ingress-nginx-controller-internal
  namespace: ingress-nginx
spec:
  externalTrafficPolicy: Local
  ports:
  - appProtocol: http
    name: http
    port: 80
    protocol: TCP
    targetPort: http
  - appProtocol: https
    name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: LoadBalancer
---

 

$ kubectl apply -f deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-internal created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
$

使用上述命令为公共和私有 NLB 创建入口,让我们使用以下命令进行验证:

$ kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer XXX.XXX.XXX.XXX ingress-nginx-external-nlb-XXXXX.elb.ap-south-1.amazonaws.com 80:31070/TCP,443:32588/TCP 41s
ingress-nginx-controller-admission ClusterIP XXX.XXX.XXX.XXX <none> 443/TCP 41s
ingress-nginx-controller-internal LoadBalancer XXX.XXX.XXX.XXX ingress-nginx-internal-nlb-XXXXX.elb.ap-south-1.amazonaws.com 80:31690/TCP,443:31672/TCP 41s
$

使用 DNS 提供商为负载均衡器添加域名记录,以便正确路由流量。在本博客中,我使用了 Route53,并使用相同的域名 ingress.example.com 为外部负载均衡器创建了一个公共主机记录,为内部负载均衡器创建了一个私有主机记录。您也可以为外部和内部负载均衡器使用不同的域名。

测试 Ingress NGINX 控制器


使用多个 Ingress 文件路由流量


让我们在不同的命名空间中部署两个应用程序,并为每个命名空间创建单独的 Ingress 文件。

使用多个 Ingress 文件路由流量
创建两个命名空间来部署应用程序

$kubectl create namespace apache-app-ns
$kubectl create namespace nginx-app-ns

验证状态
$ kubectl get ns
设置两个部署或微服务。例如:使用以下 yaml 文件创建 nginx-app 和 apache-app。

## nginx-app.yaml ##
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-app
  name: nginx-app
  namespace: nginx-app-ns
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: nginx-app
    spec:
      containers:
      - image: nginx
        name: nginx
---
apiVersion: v1
kind: Service
metadata:
  namespace: nginx-app-ns
  name: nginx-svc
  labels:
    app: nginx-app
spec:
  type: ClusterIP
  selector:
    app: nginx-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
## apache-app.yaml ###
apiVersion: apps/v1 
kind: Deployment 
metadata:
  name: apache-app
  namespace: apache-app-ns
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apache-app
  template:
    metadata:
      labels:
        app: apache-app
    spec:
      containers:
      - name: apache-app
        image: httpd:latest
        ports:
        - containerPort: 80 

--- 
apiVersion: v1 
kind: Service 
metadata:
  name: apache-svc
  namespace: apache-app-ns
  labels: 
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: apache-app

 

$ kubectl apply -f apache-app-svc.yaml
$ kubectl apply -f nginx-app.yaml

 先部署nginx 应用

### nginx-ingress.yml ##
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/add-base-url: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
  name: nginx-ingress
  namespace: nginx-app-ns
  labels:
    app: nginx
spec:
  ingressClassName: nginx
  rules:
  - host: ingress.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              number: 80
$ kubectl apply -f nginx-ingress.yml      
ingress.networking.k8s.io/nginx-ingress configured

 此 Ingress 配置确保路径包含 / 的请求会被转发到 nginx-app-ns 命名空间内的 nginx-svc 服务,并由 Ingress NGINX 控制器进行相应的 URL 重写。

ingressClassName: nginx:指定此 Ingress 使用的 Ingress 类。此处设置为 nginx,表示 Ingress NGINX 控制器应该处理此 Ingress。

# host: "your-domain.com"

请将其替换为您的域名或子域名

现在为 Apache 应用程序部署 Ingress:

### apache-app-ingress.yaml ###
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/add-base-url: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
  name: apache-ingress
  namespace: apache-app-ns
  labels:
    app: apache-app
spec:
  ingressClassName: nginx
  rules:
  - host: ingress.example.com
    http:
      paths:
      - path: /apache
        pathType: Prefix
        backend:
          service:
            name: apache-svc
            port:
              number: 80

$ kubectl apply -f apache-app-ingress.yaml                                  
ingress.networking.k8s.io/apache-ingress configured

通过使用上述命令为 apache 应用程序创建入口,并确保带有 /apache 路径的请求转发到 apache-app-ns 命名空间内的 apache-svc 服务,让我们使用以下命令验证是否创建了资源:

$ kubectl get svc -A |egrep "apache-svc|nginx-svc"
apache-app-ns apache-svc ClusterIP XX.XXX.XXX.XXX <none> 80/TCP 45m
nginx-app-ns nginx-svc ClusterIP XX.XXX.XXX.XXX <none> 80/TCP 36m
$ kubectl get ing -A |egrep "apache|nginx"     
apache-app-ns   apache-ingress                            nginx   ingress.example.com   ingress-nginx-external-nlb-XXXXX.elb.ap-south-1.amazonaws.com   80      23m
nginx-app-ns    nginx-ingress                             nginx   ingress.example.com   ingress-nginx-external-nlb-XXXXXX.elb.ap-south-1.amazonaws.com   80      26m
$

使用以下 URL 访问 nginx 和 apache 应用程序

apache-apphttp://ingress.example.com/apache

 注意:内部负载均衡器可在 VPC 内部或使用 VPN 设置访问。

使用单个 Ingress 文件路由流量


让我们在不同的命名空间中部署两个应用程序,并创建单个 Ingress 文件,使用“ExternalName”服务将流量路由到后端服务。

ExternalName 服务是一种特殊的服务,它没有选择器,而是使用 DNS。

使用单个 Ingress 文件路由流量

Routing Traffic with a Single Ingress File
### app-external-service.yaml ###
apiVersion: v1
kind: Service
metadata:
  name: nginx-external
  namespace: default
spec:
  type: ExternalName
  externalName: nginx-svc.nginx-app-ns
---
apiVersion: v1
kind: Service
metadata:
  name: apache-external
  namespace: default
spec:
  type: ExternalName
  externalName: apache-svc.apache-app-ns
$ kubectl apply -f app-external-service.yaml 
service/nginx-external created
service/apache-external created
$ 
$ kubectl get svc |egrep "apache|nginx"
apache-external                   ExternalName   <none>          apache-svc.stream-app-ns   <none>         3m41s
nginx-external                    ExternalName   <none>          nginx-svc.blog-app-ns      <none>         3m41s
$

 

此处,默认命名空间中名为 nginx-external 和 apache-external 的 Kubernetes 服务被设置为将请求重定向到 DNS 名称分别为 nginx-svc.nginx-app-ns 和 apache-svc.apache-app-ns 的外部服务。

接下来,我们将创建一个 Ingress 文件,将流量路由到这些 ExternalName 服务,确保流量被定向到正确的后端服务。

注意:我们的 Ingress 和 ExternalName 服务应部署在同一命名空间中。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/add-base-url: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
  name: nginx-ingress
  namespace: default
  labels:
    app: nginx
spec:
  ingressClassName: nginx
  rules:
  - host: ingress.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-external
            port:
              number: 80
      - path:  /apache
        pathType: Prefix
        backend:
          service:
            name: apache-external
            port:
              number: 80

$kubectl apply -f nginx-ingress.yml
ingress.networking.k8s.io/nginx-ingress created
$ 

使用以下命令测试 nginx 和 apache 应用,您也可以通过浏览器进行测试

$ curl -Ilk ingress.example.com               
HTTP/1.1 200 OK
Date: Sun, 04 May 2025 20:38:20 GMT
Content-Type: text/html
Content-Length: 615
Connection: keep-alive
Last-Modified: Sun, 04 May 2025 13:22:30 GMT
ETag: "6655da96-267"
Accept-Ranges: bytes

$ curl -Ilk ingress.example.com/apache
HTTP/1.1 200 OK
Date: Sun, 04 May 2025 20:38:25 GMT
Content-Type: text/html
Content-Length: 45
Connection: keep-alive
Last-Modified: Sun, 04 May 2025 18:53:14 GMT
ETag: "2d-432a5e4a73a80"
Accept-Ranges: bytes

两个应用程序都返回 200 响应,表示它们运行正常。

 

总结:


在本篇博文中,我们探讨了如何使用 Ingress NGINX 控制器和 AWS 负载均衡器有效地管理和路由 Kubernetes 中的流量。

通过理解和实施这些技术,您可以确保您的 Kubernetes 环境井然有序,并且您的服务能够按需访问。无论您是管理内部工作流还是处理外部请求,这些工具和配置都能提供灵活性和控制力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云攀登者-望正茂

你的鼓励是我前进的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值