前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于AWS EKS的K8S实践 - 打通外网对集群内服务的调用

基于AWS EKS的K8S实践 - 打通外网对集群内服务的调用

作者头像
shysh95
发布2023-08-23 10:07:03
4710
发布2023-08-23 10:07:03
举报
文章被收录于专栏:shysh95shysh95

集群内服务的暴露方式?

  1. service
  2. ingress

service 通常用作集群内服务之前的通信,ingress 通常用于暴露给集群外的服务使用。

由于我们这里的需求是将集群内的服务暴露给集群外的服务使用,所以我们这里选择 ingress 。

ingress controller 如何选择?

单纯的 ingress 是没有任何实际作用的,ingress 需要搭配 ingress controller 才会有意义,我们这里的需求是将集群内的服务暴露给我们的客户进行调用,相当于从外网访问我们集群内的服务,我们这里选择的是 ingress nginx controller,nginx的暴露点我们选择的是AWS NLB。

ingree nginx controller我们需要准备哪些东西?

  1. 一个public的子网
  2. 一个弹性EIP,用来分配给NLB
  3. 一个节点组(节点组),里面准备至少一台机器,用来部署ingress-controller

为什么我要给NLB分配一个EIP

由于ingress controller是我们外部流量的统一入口,我们可能会有N多个域名指向到我们的NLB,假设有天我们NLB需要删除重建,这时候没有这个EIP,你就需要把所有的DNS都改一个变,是不是想想就崩溃,而有了这个EIP,我们则不需要担心,即使重建NLB,DNS也不用修改。

ingress controller部署的节点有什么要求?

我们部署ingress controller的节点必须是public子网的机器,这样我们的服务才可以正常访问。

部署步骤

  1. 准备一个public子网,关于什么是public子网,请阅读基于AWS EKS的K8S实践 - 集群搭建

2. 准备一个节点组,节点组的机器数量按需定义,子网必须选择public的子网,并且在节点组打上 subnet-type.kubernetes.io=public:NoSchedule的污点以及network/subnet-type=public的标签,如下图:

通过为整个节点组打标签和污点,整个节点组下面的机器都会带上该污点和标签,之所以这样做是为了保证我们ingress-controller的Pod一定被调度到public的节点上,不会调度到私网的节点上,当然实现这个还需要修改ingrss controller的资源清单文件中的Deployment(主要修改标签亲和性和污点容忍)。

3. 获取ingress-controller资源清单文件

代码语言:javascript
复制
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.0/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml
 

下载下来的ingress controller资源文件我们需要对ingress-nginx-controller service进行修改,主要对其annotation进行修改:

代码语言:javascript
复制
apiVersion: v1
 
kind: Service
 
metadata:
 
  annotations:
 
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
 
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
 
    service.beta.kubernetes.io/aws-load-balancer-eip-allocations: eipalloc-xxxx
 
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
 
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
 
    service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-xxxx
 
    service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: preserve_client_ip.enabled=true
 
    service.beta.kubernetes.io/aws-load-balancer-type: 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.8.0
 
  name: ingress-nginx-controller
 
namespace: ingress-nginx
  1. aws-load-balancer-backend-protocol:NLB的协议这里选择TCP,不要选择TLS,https的验证我们可以放到ingress controller中,没必要放在AWS的NLB组件上,而且NLB默认只支持25个证书
  2. aws-load-balancer-eip-allocations:为NLB绑定我们的EIP
  3. aws-load-balancer-nlb-target-type: 指定nlb后面绑定的目标组的类型,这里的目标组里的机器就是ingress-nginx中的Pod容器,你可以理解为就是nginx
  4. aws-load-balancer-scheme:这里指定为internet-facing,表示我们的服务是暴露到互联网上的
  5. aws-load-balancer-subnets:这里指定NLB的子网,这里一定要选择public的子网
  6. aws-load-balancer-target-group-attributes:preserveclientip.enabled=true该参数是为了ingress-contrller能够取到客户端的真实IP,不设置的话默认是NLB所在机器的内网IP
  7. aws-load-balancer-type:指定我们ingress-contrller的负载均衡器是NLB

Service修改以后,我们还需要修改ingress-nginx-controller的Deployment,修改标签选择性和污点容忍,让其一定调度到我们位于public子网的工作节点上去,如下图:

上述配置修改好以后,就可以应用我们的资源清单文件了,如果没问题的话,会在AWS控制台上看到我们创建的NLB,也可以看到我们ingress-controller的Pod也创建成功,如下图:

如何解决证书问题

可以通过cert-manager解决,安装cert-manager可以通过以下命令:

代码语言:javascript
复制
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml
 

上述资源都会安装cert-manager namspace下,关于证书的日志可以查看cert-manager deployment中pod的日志。

安装完cert-manager以后还需要安装Issuer,这个需要在你对应的namesapce下面安装,我这里会在test namespace创建,Issuer的文件如下:

代码语言:javascript
复制
apiVersion: cert-manager.io/v1
 
kind: Issuer
 
metadata:
 
  name: letsencrypt-prod
 
spec:
 
  acme:
 
# The ACME server URL,这里我们用的是Let's Encrypt 签发的免费证书
 
    server: https://acme-v02.api.letsencrypt.org/directory
 
# Email address used for ACME registration
 
    email: user@example.com
 
# Name of a secret used to store the ACME account private key
 
    privateKeySecretRef:
 
      name: letsencrypt-prod
 
# Enable the HTTP-01 challenge provider
 
    solvers:
 
- http01:
 
          ingress:
 
            ingressClassName: nginx
 

https的ingress配置

代码语言:javascript
复制
kind: Ingress
 
apiVersion: networking.k8s.io/v1
 
metadata:
 
  name: test.xxxx.example.com
 
namespace: test
 
  annotations:
 
    cert-manager.io/issuer: letsencrypt-prod
 
    kubesphere.io/creator: admin
 
spec:
 
  ingressClassName: nginx
 
  tls:
 
- hosts:
 
- test.xxxx.example.com
 
      secretName: test.xxxx.example.com-tls
 
  rules:
 
- host: test.xxxx.example.com
 
      http:
 
        paths:
 
- path: /
 
            pathType: Prefix
 
            backend:
 
              service:
 
                name: xxx
 
                port:
 
                  number: 80
 
  • cert-manager.io/issuer:指定我们创建好的issuer
  • ingressClassName:这里一定要指定成nginx,这样才可以使用到我们的ingress nginx controller
  • tls.host:需要签发证书的域
  • tls.secretName:签发好的证书保存到的Secret名称,如下图:

如何解决请求体过大的问题?

ingress nginx controller在特定情况下,会因为请求体过大导致触发限制,无法正常响应请求,因此我们需要修改这个最大值,修改最大值有两种方式,一种是每个ingress单独配置,通过在ingress的annotation指定nginx.ingress.kubernetes.io/proxy-body-size: Xm来修改,另一种是全局修改,这样会对所有的nginx-ingress生效,修改方式就是修改ingress-nginx namspace下的 ingress-nginx-controller ConfigMap配置,如下图:

如何解决跨域问题?

对于来自浏览器的访问请求,会存在跨域限制,当然跨域也可以配置全局对所有的nginx ingress生效,但是这里我们选择针对每个ingress进行配置,如下:

代码语言:javascript
复制
kind: Ingress
 
apiVersion: networking.k8s.io/v1
 
metadata:
 
  name: test.xxx.eample.com
 
namespace: test
 
  annotations:
 
    nginx.ingress.kubernetes.io/cors-allow-headers: >-
 
Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
 
    nginx.ingress.kubernetes.io/cors-allow-methods: 'PUT, GET, POST, OPTIONS'
 
    nginx.ingress.kubernetes.io/cors-allow-origin: '*'
 
    nginx.ingress.kubernetes.io/enable-cors: 'true'
 
spec:
 
  ingressClassName: nginx
 
  rules:
 
- host: test.xxx.eample.com
 
      http:
 
        paths:
 
- path: /
 
            pathType: Prefix
 
            backend:
 
              service:
 
                name: xxxx
 
                port:
 
                  number: 80
 
  1. nginx.ingress.kubernetes.io/cors-allow-header:指定允许跨域的Request Header
  2. nginx.ingress.kubernetes.io/cors-allow-methods:指定允许跨域的请求方式
  3. nginx.ingress.kubernetes.io/cors-allow-origin:指定允许的源域
  4. nginx.ingress.kubernetes.io/enable-cors:开启跨域支持

如何解决白名单IP问题?

对于一些后台系统我们通常都会有白名单IP的限制,一般只允许公司的出口IP和办公VPN访问,或者一些三方在调用自己的服务时也会增加白名单限制,防止一些不合法的IP进行登录调用,ingress nginx的白名单限制需要通过以下注解来解决:

代码语言:javascript
复制
kind: Ingress
 
apiVersion: networking.k8s.io/v1
 
metadata:
 
  name: test.xxx.eample.com
 
namespace: test
 
  annotations:
 
      nginx.ingress.kubernetes.io/whitelist-source-range: >-
 
112.112.112.115/32,77.89.22.32/32
 
spec:
 
  ingressClassName: nginx
 
  rules:
 
- host: test.xxx.eample.com
 
      http:
 
        paths:
 
- path: /
 
            pathType: Prefix
 
            backend:
 
              service:
 
                name: xxxx
 
                port:
 
                  number: 80
 

nginx.ingress.kubernetes.io/whitelist-source-range:用来指定白名单中的IP或网段,上述示例表明只允许112.112.112.115和,77.89.22.32这两个IP请求我们的test.xxx.eample.com。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-06-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员修炼笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档