KubernetesIngress只是Kubernetes中的一个普通资源对象。它需要一个对应的Ingresscontroller来解析Ingress规则,对外暴露服务,比如ingress-nginx。本质上,它只是一个NginxPod,然后将请求重定向到其他内部(ClusterIP)服务。Pod本身也是通过Kubernetes服务暴露出来的,最常见的方式是通过LoadBalancer来实现。在同一篇文章中,我们希望通过一个简单明了的概述,让您了解KubernetesIngress背后的内容,让您更容易理解所使用的Ingress。我们可以使用Ingress将内部服务暴露到集群外部。它为您节省了宝贵的静态IP,因为您不需要声明多个LoadBalancer服务。这一次,它还可以进行更多的附加配置。我们用一个简单的例子来说明Ingress。简单的HTTP服务器首先,让我们回到容器和Kubernetes之前的时代。过去,我们会使用(Nginx)HTTP服务器来托管我们的服务。它可以通过HTTP协议接收对特定文件路径的请求,然后检查文件系统中的文件路径,如果存在则返回。比如在Nginx中,我们可以通过如下配置来实现这个功能。location/folder{root/var/www/;indexindex.html;}除了上面提到的功能外,我们还可以在HTTP服务器收到请求(意思是充当代理)时,将请求重定向到另一台服务器来重定向服务器对客户端的响应。对于客户端来说,什么都没有改变,收到的结果仍然是请求的文件(如果存在的话)。同样在Nginx中,重定向可以这样配置:location/folder{proxy_passhttp://second-nginx-server:8000;}这意味着Nginx可以从文件系统服务文件,或者通过代理将响应直接重定向到其他服务器并返回它们的响应。简单的Kubernetes示例在使用ClusterIP服务在Kubernetes中部署应用程序之后,我们应该首先了解KubernetesService服务(在上一篇文章中进行了解释)。例如,我们有两个工作节点和两个服务service-nginx和service-python,它们指向不同的pod。这两个服务没有被调度到任何一个特定的节点上,也就是在任何一个节点上都有可能,如下图所示:在集群内部,我们可以通过它们的Service服务来请求NginxPod和PythonPod。现在我们希望这些服务也可以从集群外部访问。如上所述,我们需要将这些服务转换为LoadBalancer服务。使用LoadBalancer服务当然,使用LoadBalancer服务的前提是我们的Kubernetes集群的托管服务商必须能够支持。如果支持,我们可以将上面的ClusterIP服务转换为LoadBalancer服务,创建两个外部负载均衡器来重新加载请求。定向到我们的节点IP,然后重定向到内部ClusterIP服务。我们可以看到两个LoadBalancer都有自己的IP,如果我们向LoadBalancer22.33.44.55发送请求,它将被重定向到我们内部的service-nginx服务。如果请求发送到77.66.55.44,它将被重定向到我们的内部服务-python服务。这样确实很方便,但是要知道IP地址是比较难得的,而且价格也不便宜。想象一下,我们的Kubernetes集群中不仅有两个服务,如果有很多,为这些服务创建LoadBalancer的成本将成倍增加。那么有没有另一种方案可以让我们只使用一个LoadBalancer来转发请求到我们内部的服务呢?让我们首先手动探索这个问题(非Kubernetes)。手动配置Nginx代理服务我们知道Nginx可以作为代理,所以我们很容易想到运行一个Nginx来代理我们的服务。如下图所示,我们添加了一个名为service-nginx-proxy的新服务,它实际上是我们唯一的LoadBalancer服务。service-nginx-proxy仍会指向一个或多个Nginx-pod-endpoints(图中为简单起见未标出),而之前的其他两个服务已转换为简单的ClusterIP服务。可以看出,我们只分配了一个IP地址为11.22.33.44的负载均衡器。我们用黄色标记不同的http请求路径。它们的目标相同,但包含不同的请求URL。service-nginx-proxy服务将使用请求的URL来决定他们应该将请求重定向到哪个服务。上图中我们有两个后台服务,分别用红色和蓝色标记,红色重定向到service-nginx服务,蓝色重定向到service-python服务。对应的Nginx代理配置如下:location/folder{proxy_passhttp://service-nginx:3001;}location/other{proxy_passhttp://service-python:3002;}但是现在我们需要手动配置service-nginx-以代理服务为例,如果一个新的请求路径需要路由到其他服务,我们需要重新配置Nginx配置使其生效,但这确实是一个可行的方案,只是有点麻烦。而KubernetesIngress就是为了让我们的配置更简单、更智能、更容易管理。因此,在Kubernetes集群中,我们将使用Ingress代替上述手动配置,将服务暴露到集群外部。使用KubernetesIngress现在我们将上面手动代理配置转换为KubernetesIngress,如下图,我们只是使用了一个预先配置好的Nginx(Ingress),它已经为我们完成了所有的代理重定向工作,这为我们节省了很多手动配置工作。这实际上解释了KubernetesIngress是什么。让我们看一些配置示例。安装入口控制器。Ingress只是Kubernetes的一个资源对象。在这个资源中,我们可以配置我们的服务路由规则,但是要真正识别这个Ingress并提供代理路由功能,我们需要安装相应的控制器。为了要达到。$kubectlapply-fhttps://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml$kubectlapply-fhttps://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml使用如下命令查看安装在命名空间ingress-nginx中的k8s资源。我们可以看到一个普通的LoadBalancer服务,它有一个外部IP和一个拥有的pod,我们可以使用命令kubectlexec输入它,其中包含一个预配置的Nginx服务器。nginx.conf文件包含各种代理重定向设置和其他相关配置。Ingress配置示例我们使用的Ingressyaml示例可能如下所示。#justexample,nottestedapiVersion:networking.k8s.io/v1beta1kind:Ingressmetadata:annotations:kubernetes.io/ingress.class:nginxnamespace:defaultname:test-ingressspec:rules:-http:paths:-path:/folderbackend:serviceName:service-nginxservicePort:3001-http:paths:-path:/otherbackend:serviceName:service-pythonservicePort:3002和其他资源对象一样,使用kubectlcreate-fingress.yaml创建这个资源对象即可。创建完成后,Ingress对象会被上面安装的Ingresscontroller转换为对应的Nginx配置。如果您的一项内部服务(Ingress应重定向到的服务)位于不同的命名空间中怎么办?因为我们定义的Ingress资源是在命名空间级别的。在Ingress配置中,只能对同一命名空间中的服务进行重定向。如果您定义了多个Ingressyaml配置,那么这些配置将由单个Ingress控制器合并到单个Nginx配置中。这意味着每个人都在使用相同的LoadBalancerIP。配置IngressNginx有时候我们需要对IngressNginx做一些微调配置,我们可以通过Ingress资源对象中的注解来完成。例如,我们可以配置通常直接在Nginx中的各种配置选项。种类:Ingressmetadata:名称:ingressannotations:kubernetes.io/ingress.class:nginxnginx.ingress.kubernetes.io/proxy-connect-timeout:'30'nginx.ingress.kubernetes.io/proxy-send-timeout:'500'nginx.ingress.kubernetes.io/proxy-read-timeout:'500'nginx.ingress.kubernetes.io/send-timeout:"500"nginx.ingress.kubernetes.io/enable-cors:"true"nginx.ingress.kubernetes.io/cors-allow-methods:"*"nginx.ingress.kubernetes.io/cors-allow-origin:"*"...另外,还可以做更细粒度的规则配置,如下:nginx.ingress.kubernetes.io/configuration-snippet:|if($host='www.qikqiak.com'){rewrite^https://qikqiak.com$request_uripermanent;}这些注解会转化为Nginx的配置,你可以通过手动连接(kubectlexec)到nginxpod来检查这些配置。更多ingress-nginx的配置和使用请参考官方文档:https://github.com/kubernetes/ingress-nginx/tree/master/docs/user-guide/nginx-configurationhttps://github。com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md#lua-resty-waf查看ingress-nginx日志排查问题,查看入口控制器。使用curl测试如果我们要测试Ingress重定向规则,最好使用curl-v[yourhost.com](http://yourhost.com)而不是浏览器,这样可以避免缓存带来的问题。重定向规则在本文的示例中,我们使用/folder和/other/directory等路径来重定向到不同的服务。此外,我们还可以通过主机名来区分请求,比如api.myurl.com和site.myurl。com重定向到不同的内部ClusterIP服务。apiVersion:networking.k8s.io/v1beta1kind:Ingressmetadata:name:simple-fanout-examplespec:rules:-host:api.myurl.comhttp:paths:-path:/foobackend:serviceName:service1servicePort:4200-path:/barbackend:serviceName:service2servicePort:8080-host:website.myurl.comhttp:paths:-path:/backend:serviceName:service3servicePort:3333SSL/HTTPS可能我们希望网站使用安全的HTTPS服务,而KubernetesIngress也提供了简单的TLS验证,这意味着它处理所有SSL通信,解密/验证SSL请求,并将这些解密的请求发送到内部服务。如果你的多个内部服务使用同一个(可能是通配符)SSL证书,我们只需要在Ingress上配置一次即可,不需要配置内部服务。Ingress可以使用配置好的TLSKubernetesSecret来配置SSL证书。apiVersion:networking.k8s.io/v1beta1kind:Ingressmetadata:name:tls-example-ingressspec:tls:-hosts:-sslexample.foo.comsecretName:testsecret-tlsrules:-host:sslexample.foo.comhttp:paths:-path:/backend:serviceName:service1servicePort:80但是需要注意的是,如果你在不同的命名空间中有多个Ingress资源,你的TLSsecret也必须在你使用的Ingress资源的所有命名空间中可用。总结这里我们简单介绍一下KubernetesIngress的原理,简单来说:它只是一种方便配置Nginx服务器的方式,可以将请求重定向到其他内部服务。这为我们节省了宝贵的静态IP和LoadBalancers资源。另外需要注意的是,还有其他类型的KubernetesIngress。它们内部没有安装Nginx服务,但可能会使用其他代理技术来实现上述所有功能。
