亚马逊AWS官方博客

在 EKS 平台上合并 ALB Ingress Controller

1.  背景

Kubernetes Ingress 是一种 API 对象,借助它可以管理对集群中运行的 Kubernetes 服务的外部(或)内部 HTTPS访问,通过ALB ingress controller可以在kubernetes上部署服务时自动触发创建 ALB 以及必要的 AWS 支持资源。下图详细描述了用户定义了 Ingress 资源时 aws-alb-ingress-controller 将会创建的 AWS 组件。

 

当客户在EKS上部署微服务时,他们发现AWS ALB Ingress Controller会为每个入口资源创建一个新的ALB。 当客户有数百个微服务时,也会生成数百个ALB,从管理和经济成本上分析,可能会让客户的使用成本变得非常高。 所以支持跨ingress资源重用ALB是客户的一个重要需求。 此外,每个帐户ALB的数量限制为50个,如果超过此限制需要不断的提升ALB的数量,这增加了客户运维的风险和负担。因此,针对这个现状,结合开源项目实现了一套合并ALB ingress controller的方法来解决客户的问题,其原理是:合并Ingress Controller并允许创建ingress资源,这些ingress资源将被组合在一起以创建将由同一控制器管理的新入口资源,工作流程见下图:

 

 

2.  合并过程

1)  前置条件

  • Create an AWS account
  • Create a Workspace
  • Create an SSH key
  • Install Kubernetes Tools
  • Create an IAM role for your Workspace
  • Attach the IAM role to your Workspace
  • Update IAM settings for your Workspace

Note: 前置条件过程可以参考链接: https://eksworkshop.com/eksctl/

 

2)  安装kubectl过程

创建安装目录(可选)

$mkdir -p ~/.kube

安装kubectl:

$sudo curl --silent --location -o /usr/local/bin/kubectl " https://storage.googleapis.com/kubernetes-release/release/v1.14.9/bin/linux/amd64/kubectl" sudo chmod +x /usr/local/bin/kubectl

安装AWS IAM Authenticator(或升级到AWS CLI 的版本 1.16.232 或更高版本中):

$ go get -u -v github.com/kubernetes-sigs/aws-iam-authenticator/cmd/aws-iam-authenticator

sudo mv ~/go/bin/aws-iam-authenticator /usr/local/bin/aws-iam-authenticator

 

注:AWS CLI 的版本 1.16.232 或更高版本中可用的 aws eks get-token 命令支持客户端安全令牌创建

,所以也可以升级当前的AWS cli到最新版本,可以参考如下链接:

https://docs.thinkwithwp.com/zh_cn/cli/latest/userguide/install-cliv2-linux.html

 

安装JQ:

sudo yum -y install jq

 

下载与安装 eksctl :

$curl --silent --location "https://github.com/weaveworks/eksctl/releases/download/latest_release/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp

$sudo mv -v /tmp/eksctl /usr/local/bin

$eksctl version

3)  创建EKS 集群(命令行中的AWS_REGION换成真实region)并开启访问alb-ingress权限

$eksctl create cluster --name=eksworkshop-eksctl --nodes=3 --node-ami=auto --region=${AWS_REGION} --alb-ingress-access

$kubectl get nodes

4)  部署Ingress_controller

$kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.3/docs/examples/rbac-role.yaml

$ curl -sS "https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.0.0/docs/examples/alb-ingress-controller.yaml" > alb-ingress-controller.yaml



Note:Change the parameter of alb-ingress-controller.yaml:–cluster-name = cluster-name

$ kubectl apply -f alb-ingress-controller.yaml

$kubectl logs -n kube-system $(kubectl get po -n kube-system | egrep -o alb-ingress[a-zA-Z0-9-]+)

 

5)  安装Ingress-Merge

$helm install --namespace kube-system --name ingress-merge ./helm

6)  部署demo application 2048

$curl -sS "https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.3/docs/examples/2048/2048-namespace.yaml" > 2048-namespace.yaml

$ curl -sS "https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.3/docs/examples/2048/2048-deployment.yaml " > 2048-deployment.yaml

$ curl -sS "https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.3/docs/examples/2048/2048-service.yaml" > 2048-service.yaml

$kubectl apply -f 2048-namespace.yaml

$kubectl apply -f 2048-deployment.yaml

$kubectl apply -f 2048-service.yaml

 

7)  部署demo application echoserver

$ curl -sS "https://github.com/kubernetes-sigs/aws-alb-ingress-controller/blob/master/docs/examples/echoservice/echoserver-deployment.yaml" > echoserver-deployment.yaml

$ curl -sS "https://github.com/kubernetes-sigs/aws-alb-ingress-controller/blob/master/docs/examples/echoservice/echoserver-service.yaml" > echoserver-service.yaml

     Note: 修改echoserver相关的yaml文件中的namespace为同一个.

8)  创建configmap

$ cat merge-ingress-cm.yaml

apiVersion: v1

kind: ConfigMap

metadata:

  name: merged-ingress

  namespace: game

data:

  annotations: |

    kubernetes.io/ingress.class: alb

    alb.ingress.kubernetes.io/scheme: internet-facing

$kubectl apply -f merge-ingress-cm.yaml

 

9)  创建Merge ingress

$ cat merge-ingress.yaml

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: echoserver-ingress

  namespace: game

  annotations:

    kubernetes.io/ingress.class: merge

    merge.ingress.kubernetes.io/config: merged-ingress

  labels:

    app: echoserver-ingress

spec:

  rules:

    - http:

        paths:

          - path: /echo

            backend:

              serviceName: echoserver

              servicePort: 8080

---

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: "2048-ingress"

  namespace: "game"

  annotations:

    kubernetes.io/ingress.class: merge

    merge.ingress.kubernetes.io/config: merged-ingress

  labels:

    app: 2048-ingress

spec:

  rules:

    - http:

        paths:

          - path: /*

            backend:

              serviceName: "service-2048"

              servicePort: 80

$kubectl apply -f merge-ingress.yaml



$ cat ingress.yaml

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: merged-ingress

  namespace: game

  annotations:

    kubernetes.io/ingress.class: alb

    alb.ingress.kubernetes.io/scheme: internet-facing

spec:

  rules:

    - http:

        paths:

        - path: /echo

          backend:

            serviceName: echoserver

            servicePort: 8080

        - path: /game

          backend:

            serviceName: service-2048

            servicePort: 80

$kubectl apply -f ingress.yaml

 

10) 检查生成的ALB和对应的规则


11) 访问这个服务来验证,出现如下内容即表示成功

第一个是echoserver:

 

第二个是2048:

 

注:请自行修改nginx中对于path的处理逻辑。

12) 总结

通过ingress-merge-controller将服务对应的rules附加到ALB上,这样我们完成了原来需要两个ALB合并成一个ALB的目的,减少了客户管理的ALB的数量并由此可以降低成本。

需要提醒大家以下几点:

  • Ingress controller 只支持http 和Https协议;
  • 服务只支持nodeport和Loadbalancer 类型,即:Type=NodePort 或Service.Type=LoadBalancer

13) 参考资料

https://github.com/jakubkulhan/ingress-merge

https://github.com/kubernetes-sigs/aws-alb-ingress-controller

 

本篇作者

王建利

王建利,AWS解决方案架构师,主要负责企业级大客户的上云工作,服务客户涵盖从能源,互联网,传统生产制造,擅长DevOps和容器领域。具备 15 年 IT 专业服务经验,历任程序设计师、项目经理、解决方案架构师。