k8s使用nginx-ingress代理转发请求

1,566 阅读2分钟

ingress介绍

通常情况下,我们的软件部署架构,都是类似下面的方式:

image.png

应用服务器部署在一个内部网络,外部用户没法直接访问,只能通过软硬件负载均衡器(硬件像F5,Radware,软件有LVS,haproxy,nginx等)反向代理用户请求,将请求转发到内网服务器进行处理。这些负载均衡设施主要提供负载均衡、路由规则 、外部域名访问、SSL、基于名称的虚拟主机等功能。

k8s集群架构类似,Kubernetes中的Service只能在集群内部网络中通过IP地址进行访问,外部流量无法穿透至集群内部网络,同样,你需要一个反向代理中间件(你也可以把它理解为微服务架构中的网关)来转发请求,这个组件在K8S集群中就叫Ingress Controller.

image.png

Kubernetes官方目前支持和维护 AWS、 GCE 和 Nginx Ingress Controller。其它还有很多第三方的Ingress Controller实现,如haproxy、kong、traefik、Istio、Apache APISIX等,这里面很多组件在微服务架构中都是作为网关来使用的。

image.png

安装部署nginx-ingress

使用helm来安装nginx-ingress

helm upgrade --install ingress-nginx ingress-nginx  --repo https://kubernetes.github.io/ingress-nginx  --namespace ingress-nginx --create-namespace

image.png

打开rancher面板发现,nginx-ingress一直处于pending状态。 image.png

这是因为我之前开启了traefik,取消勾选即可(rancher desktop会自动重启k8s) image.png

重启k8s后状态正常

image.png

Maven Pom.xml增加相关配置


<properties>
    <jkube.createExternalUrls>true</jkube.createExternalUrls>
</properties>


<plugin>
    <groupId>org.eclipse.jkube</groupId>
    <artifactId>kubernetes-maven-plugin</artifactId>
    <version>${jkube.version}</version>

    <configuration>
        <enricher>
            <config>
                <jkube-service>
                    <type>LoadBalancer</type>
                </jkube-service>
            </config>
        </enricher>
        <resources>
            <ingress>
                <ingressRules>
                    <ingressRule>
                        <host>codyzeng.k8s.com</host>
                        <paths>
                            <path>
                                <pathType>ImplementationSpecific</pathType>
                                <path>/</path>
                                <serviceName>${project.artifactId}</serviceName>
                                <servicePort>8080</servicePort>
                            </path>
                        </paths>
                    </ingressRule>
                </ingressRules>
            </ingress>
        </resources>
    </configuration>
</plugin>

修改本地hosts文件,配置主机名称

127.0.0.1 codyzeng.k8s.com

生成k8s资源描述文件

 mvn k8s:resource 

生成的资源描述文件(目录:\target\classes\META-INF\jkube):

  • kubernetes.yml
  • kubernetes/工程名-deployment.yml
  • kubernetes/工程名-service.yml
  • kubernetes/工程名-ingress.yml

部署成功,但无法正常访问

执行以下命令部署至k8s.

 mvn k8s:apply 

部署完成发现仍无法通过配置的主机名称直接访问,查看ingress-nginx-controller日志,提示缺少IngressClassName配置

image.png

手动添加一下配置:ingressClassName: nginx

nginx-ingress 控制器还可以通过参数 --watch-ingress-without-class 来配置不需要定义默认的 IngressClass

  spec:
    ingressClassName: nginx
    rules:
    - host: codyzeng.k8s.com
      http:
        paths:
        - backend:
            service:
              name: nginx-ingress
              port:
                number: 8080
          path: /
          pathType: ImplementationSpecific

或者也可以像下面配置一样,将一个 IngressClass 资源的 ingressclass.kubernetes.io/is-default-class 注解设置为 true 将确保新的未指定 ingressClassName 字段的 Ingress 能够分配为这个默认的 IngressClass.

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  labels:
    app.kubernetes.io/component: controller
  name: nginx-example
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
spec:
  controller: k8s.io/ingress-nginx

部署后访问成功:

再执行以下命令部署至k8s环境.

 mvn k8s:apply 

打开浏览器输入地址:codyzeng.k8s.com。OK!有了 image.png