Kubernetes Ingresses (1)

2023-08-28 15:56:10 浏览数 (1)

在连接上一个 k8s cluster 后执行下面的命令可以看到系统中的ingressclasses。这篇文字用来帮助自己理解下面几行简单的输出。

╰─$ kubectl get ingressclass NAME CONTROLLER PARAMETERS AGEawslb ingress.k8s.aws/alb IngressClassParams.elbv2.k8s.aws/alb 20dnginx nginx.org/ingress-controller <none> 30dos-nginx k8s.io/ingress-nginx <none> 30d

Mental Model

在Kubernets里经常会提到Pod,Service,Ingress,Ingress Controller, Ingress Class,那他们之间有什么逻辑关系呢?

Pod

Pod用于把几个相关的containers封装在一起对外提供业务服务,containers之间可以直接通过localhost通讯。而如果想访问POD服务只能凭借POD的IP,这个IP也是K8S集群内部可见,而POD的IP在每次重建后都会变化,这显然是不可接受的。

Service Service就是为了解决这个问题而生,通过service.yaml可以定义 1)这个service的name/namespace;2)由selector定义这个service对应的PODs;3)再通过定义service port和pod port的映射关系,就可以通过Service的名称访问PODs提供的服务了。Service借助自己对Pod自动发现的能力、服务名到POD IP的解析能力、简单的负载均衡能力,成为在Kubernets集群内部暴露Pod的不二之选。

Ingress / Ingress Controller / Ingerss Class Service解决了我们在k8s集群内部访问‘服务’的问题。如果想从集群外部访问‘服务’呢?这正是“Ingress机制”七层路由存在的意义。这里的Ingress机制由Ingress Controller、Ingress这两个概念组成。

作为码农,接触较多的一般是Ingress。这是因为Ingress Controller一旦部署到Kubernetes Cluster就很少会再去改动,而需要经常改动的应用路由规则都是在Ingress这个Kubernets API对象(或者说是在ingress.yaml文件)完成的。实际上,Ingress Controller实例才是真正执行将用户请求路由到Service进而到Pod的部件。Ingress只是我们定义请求到Service的路由规则的对象。

既然“ingress“的核心功能就是7层路由/反向代理,那么借助早已存在的Nginx、HAProxy等产品实现IngressController就是很自然的想法了。另一个ingress controller的实现类别可以划分到service mesh阵营,比如Istio Ingerss、Gloo等。

k8s官网列出的一些Ingerss Controller实现 https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/

而这篇文章 https://blog.palark.com/comparing-ingress-controllers-for-kubernetes/ 详细讲解了各种Ingress Controller的特性以方便我们根据自己项目的需求做出选择。直接贴上文章的干货图片:

在一个Kubernets集群里可以定义多个不同Ingress Controller实现/类型,那么Ingress对象如何知道自己的数据是提供给哪个Ingress Controller的呢?

在Kubernetes 1.18之前,是通过在Ingress的一个annotation`kubernets.io/ingress.class` 来声明。

在Kubernetes 1.18正式引入了一个新的[k8s资源对象 IngressClass](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) 来帮助Ingress定义它绑定到哪个IngressController

下面是一个官网的IngressClass对象定义示例,`spec.controll`定义了IngressController的实现, `spec.parameters` 相当于定义了你可以在Ingerss对象里可以向这个IngressController对象能够传递的参数,当然这些参数也是这种IngressControll必须支持的。不同的Ingress Controller实现其需要的parameter肯定是不同的,而k8s 1.18之前通过annoation给IngerssController传递参数的方式就显得比较随意无章可循了,这应该也是IngressClass出现的一个原因。

代码语言:javascript复制
   apiVersion: networking.k8s.io/v1
    kind: IngressClass
    metadata:
      name: external-lb
    spec:
      controller: example.com/ingress-controller
      parameters:
        apiGroup: k8s.example.com
        kind: IngressParameters
        name: external-lb

有了IngressClass,那么在Ingress中只要设置 `spec.ingressClassName` 为某个IngerssClass的名字,那么就意味着这个Ingress的配置就会被这个IngerssClass所对应的IngressController所获取并被这个IngressControll生成为对应的路由rules,从而完成把一个集群外请求路由到Service的功能。

以上就是关于Kubernetes里Ingerss的几个基本概念。

有关Nginx的IngressController

基于Nginx实现的IngressController分为`Kubernets社区版`和`Nginx版`。

Kubernets社区版由Kubernetes社区和F5 Nginx工程师基于开源的Nginx实现,其官网 [code](https://github.com/kubernetes/ingress-nginx) [doc](https://kubernetes.github.io/ingress-nginx/)。

Nginx版自己又分为免费的基于开源Nginx的IngressController实现和商业版。Nginx开源版[code](https://github.com/nginxinc/kubernetes-ingress) [doc](https://docs.nginx.com/nginx-ingress-controller/)。

所以就开源的版本来说,一个是Kubernets社区版,一个是Nginx开源版,两个都是基于开源的Nginx实现的,只是owner不通。表现在IngressClass的定义中,就是字段 `spec.controller` 的值一个是Kubernets社区版的 `k8s.io/ingress-nginx`, 一个是nginx开源版的 `nginx.org/ingress-controller`

下面这个表格 https://gist.github.com/grigorkh/f8e4fd73e99f0fde06a51e2ed7c2156c 列出了Nginx Ingress Controller的 Kubernets社区版和Nginx开源版的区别。可以看到,两者差别不大,k8s社区版功能略好于Nginx开源版。而Nginx开源版因为没有使用Lua性能又好于k8s社区版。

Aspect or Feature

kubernetes/ingress-nginx

nginxinc/kubernetes-ingress with NGINX

nginxinc/kubernetes-ingress with NGINX Plus

Fundamental

Authors

Kubernetes community

NGINX Inc and community

NGINX Inc and community

NGINX version

Custom NGINX build that includes several third-party modules

NGINX official mainline build

NGINX Plus

Commercial support

N/A

N/A

Included

Implemented in

Go/Lua (while Nginx is written in C)

Go/Python

Go/Python

Load balancing configuration via the Ingress resource

Merging Ingress rules with the same host

Supported

Supported via Mergeable Ingresses

Supported via Mergeable Ingresses

HTTP load balancing extensions - Annotations

See the supported annotations

See the supported annotations

See the supported annotations

HTTP load balancing extensions -- ConfigMap

See the supported ConfigMap keys

See the supported ConfigMap keys

See the supported ConfigMap keys

TCP/UDP

Supported via a ConfigMap

Supported via custom resources

Supported via custom resources

Websocket

Supported

Supported via an annotation

Supported via an annotation

TCP SSL Passthrough

Supported via a ConfigMap

Supported via custom resources

Supported via custom resources

JWT validation

Not supported

Not supported

Supported

Session persistence

Supported via a third-party module

Not supported

Supported

Canary testing (by header, cookie, weight)

Supported via annotations

Supported via custom resources

Supported via custom resources

Configuration templates

See the template

See the templates

See the templates

Load balancing configuration via Custom Resources

HTTP load balancing

Not supported

See VirtualServer and VirtualServerRoute resources

See VirtualServer and VirtualServerRoute resources

TCP/UDP load balancing

Not supported

See TransportServer resource

See TransportServer resource

TCP SSL Passthrough load balancing

Not supported

See TransportServer resource

See TransportServer resource

Deployment

Command-line arguments

See the arguments

See the arguments

See the arguments

TLS certificate and key for the default server

Required as a command-line argument/ auto-generated

Required as a command-line argument

Required as a command-line argument

Helm chart

Supported

Supported

Supported

Operator

Not supported

Supported

Supported

Operational

Reporting the IP address(es) of the Ingress controller into Ingress resources

Supported

Supported

Supported

Extended Status

Supported via a third-party module

Not supported

Supported

Prometheus Integration

Supported

Supported

Supported

Dynamic reconfiguration of endpoints (no configuration reloading)

Supported with a third-party Lua module

Not supported

Supported

现在再回到文章开头的命令输出,是不是看到的东西更多了?

代码语言:javascript复制
   ╰─$ kubectl get ingressclass        
    NAME       CONTROLLER                     PARAMETERS                             AGE
    awslb      ingress.k8s.aws/alb            IngressClassParams.elbv2.k8s.aws/alb   20d
    nginx      nginx.org/ingress-controller   <none>                                 30d
    os-nginx   k8s.io/ingress-nginx           <none>                                 30d

References:

[1]: [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)

[2]: [IngressController](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/)

[3]: [IngressClass](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class)

[4]: [Comparing Ingress Controllers for Kubernetes](https://blog.palark.com/comparing-ingress-controllers-for-kubernetes/)

[5]: [基于Nginx的Ingress Controller在社区和商业版之间的比较](https://www.nginx.com/blogguide-to-choosing-ingress-controller-part-4-nginx-ingress-controller-options/)

[6]: [Kubernetes社区版](https://kubernetes.github.io/ingress-nginx/)

[7]: [Nginx开源版](https://kubernetes.github.io/ingress-nginx/)

[8]: [Nginx Ingress Controll社区版和Nginx开源版的比较](https://grigorkh.medium.com/there-are-two-nginx-ingress-controllers-for-k8s-what-44c7b548e678)

0 人点赞