k8s之ingress

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

写在前面

本文接k8s之Service

在这里插入图片描述
k8s之Service 一文中我们分析了service API对象该API对象能够实现多个POD的负载均衡访问以及服务的自动发现但是这是一种基于四层的负载均衡方式只支持基于IP地址的负载均衡而现在业务几乎都是基于http、https的七层协议即需要能够根据域名域名后缀甚至请求头等信息来负载均衡为了解决这个问题k8s在Service API的基础上又扩展出来了ingress API对象但其实ingress仅仅是一个路由配置规则并不负责规则的解析但大家习惯上都称这种基于七层协议的负载均衡机制为ingress后面我们也会看到这些内容。下面我们就开始吧

1ingress的作用

ingress API对象如下

dongyunqi@mongodaddy:~/k8s$ kubectl api-resources|egrep -w 'Ingress|KIND'
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
ingresses                         ing          networking.k8s.io/v1                   true         Ingress

networking.k8s.io/v1可以看到其是属于k8s网络系统相关的API对象它在网络系统中的作用就是来定义路由规则如xxx.com/访问Service1xxx.com/user访问service2xxx.com/customer访问service3这样。但其也仅仅是给出相关的规则定义并没有具体规则的解析以及流量的转发机制那么为什么ingress不增加这个功能呢还是因为单一职责的原则为此k8s又专门定义了另一个API对象ingress controller所以准确来说ingress controller才是核心因为它是流量的入口。如此重要的一个AP对象按道理来讲k8s应该自己来开发才是但不知道出于什么原因将这个关键点交给了社区开发只要符合ingress规则即可即能够解析ingress定义的规则并按照此规则来转发流量。目前比较主流的ingress controller实现包括

社区的 Kubernetes Ingress Controllerhttps://github.com/kubernetes/ingress-nginx、
Nginx 公司自己的 Nginx Ingress Controllerhttps://github.com/nginxinc/kubernetes-ingress、
基于 OpenResty 的 Kong Ingress Controllerhttps://github.com/Kong/kubernetes-ingress-controller

本文以Nginx公司开发实现的 Ingress Controller 为例来进行说明此时结构如下图
在这里插入图片描述

到这里应该就告一段了k8s的ingres就可以安安心心的对外提供服务了但是现实总是让你不得安生,在用户的实际使用过程中因为k8s仅仅支持一个ingress controller一些问题就暴露了如下

1一个ingress controller当ingress规则比较多时规则解析压力会比较大可能成为性能瓶颈
2因为业务需要确实需要多个ingress controller
3各种路由规则都混杂在一个ingress中造成路由规则的维护成本过高

核心问题就是不能只支持一个ingress controller那么为了解决这个问题k8s又引入了一个新的API对象即ingress class该对象的作用就是在ingress controller和ingress中间起一个转换器的作用。所以最后的结构就是这样子的
在这里插入图片描述
其中红色半透明区域多组来支持多个ingress controller但实际上我们一般只会使用一个ingress controller这样ingress主要结构我们就介绍完成了接下来看下实际的操作。

2实战

2.1定义ingress路由规则和ingress class

首先我们来定义路由规则访问本文 已经定义好的service生成yaml模板如下

dongyunqi@mongodaddy:~/k8s$ export out="--dry-run=client -o yaml" && kubectl create ing ngx-ing --rule="ngx.test/=ngx-svc:80" --class=ngx-ink $out
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  creationTimestamp: null
  name: ngx-ing
spec:
  ingressClassName: ngx-ink
  rules:
  - host: ngx.test
    http:
      paths:
      - backend:
          service:
            name: ngx-svc
            port:
              number: 80
        path: /
        pathType: Exact
status:
  loadBalancer: {}

ingressClassName: ngx-ink定义要使用ingress class是ngx-ink(后面会定义)- host: ngx.test设置规则的主域名是ngx.test,path: /访问的路径是/即将访问http://ngx.test/时会匹配到该规则。name: ngx-svc使用名称为ngx-svc的servicenumber: 80后端服务的端口号为80,pathType: Exact代表使用精准匹配。这里用到了ingress class只有一个比较关键的controller配置用来设置具体的ingress controller这里为了简单起见将ingress和ingress class的yaml定义在一起如下

dongyunqi@mongodaddy:~/k8s$ cat ingress.yml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ngx-ing
  
spec:

  ingressClassName: ngx-ink
  
  rules:
  - host: ngx.test
    http:
      paths:
      - path: /
        pathType: Exact
        backend:
          service:
            name: ngx-svc
            port:
              number: 80
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: ngx-ink

spec:
  controller: nginx.org/ingress-controller

ingress class定义的controller是nginx.org/ingress-controller,这是个固定的名称。apply应用之后查看二者

dongyunqi@mongodaddy:~/k8s$ kubectl get ingress
NAME      CLASS     HOSTS      ADDRESS   PORTS   AGE
ngx-ing   ngx-ink   ngx.test             80      20h
dongyunqi@mongodaddy:~/k8s$ kubectl get ingressclass
NAME      CONTROLLER                     PARAMETERS   AGE
ngx-ink   nginx.org/ingress-controller   <none>       20h

重点describe下ingress看下路由信息是否生效

nqi@mongodaddy:~/k8s$ kubectl decribe ingress ngx-ing
error: unknown command "decribe" for "kubectl"

Did you mean this?
	describe
dongyunqi@mongodaddy:~/k8s$ kubectl describe ingress ngx-ing
Name:             ngx-ing
Labels:           <none>
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host        Path  Backends
  ----        ----  --------
  ngx.test    
              /   ngx-svc:80 (10.10.1.10:80,10.10.1.9:80)
Annotations:  <none>
Events:       <none>

Rules:可以看出当完整路径为ngx.test/时匹配的后端服务是ngx-svc:80 (10.10.1.10:80,10.10.1.9:80)后端服务的POD信息也都列举了出来。此时结构可以参考下图

在这里插入图片描述

2.2定义ingress controller

ingress controller的定义相对就要麻烦一些首先需要先安装依赖的相关信息如congigmapsecret等相关的文件可以从这里 下载然后执行如下命令

kubectl apply -f common/ns-and-sa.yaml
kubectl apply -f rbac/rbac.yaml
kubectl apply -f common/nginx-config.yaml
kubectl apply -f common/default-server-secret.yaml
kubectl apply -f crds/k8s.nginx.org_globalconfigurations.yaml
kubectl apply -f crds/k8s.nginx.org_policies.yaml
kubectl apply -f crds/k8s.nginx.org_transportservers.yaml
kubectl apply -f crds/k8s.nginx.org_virtualserverroutes.yaml
kubectl apply -f crds/k8s.nginx.org_virtualservers.yaml

然后我们可以从这里 下载ingress controller的yaml然后就可以应用yaml了:

kubectl apply -f kic.yml

然后查看注意此时要带上命名空间否则从default命名空间是找不到的

dongyunqi@mongodaddy:~/k8s$ kubectl get deploy -n nginx-ingress
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
ngx-kic-dep   1/1     1            1           7h50m
dongyunqi@mongodaddy:~/k8s$ kubectl get pod -n nginx-ingress
NAME                           READY   STATUS    RESTARTS   AGE
ngx-kic-dep-67c7cf6d5f-7v7kw   1/1     Running   0          7h50m

可以看到ingress controller也是已pod来运行的(这似乎是句废话),此时结构如下图

在这里插入图片描述

但是因为POD是无法直接在外部访问的所以我们方便起见使用port-forward直接映射端口到Node节点port-forward在测试的时候用处还是比较大的如下

kubectl port-forward -n nginx-ingress ngx-kic-dep-8859b7b86-cplgp 8080:80 &

因为ingress是基于域名ngx.test来解析的所以我们需要配置host来映射到127.0.0.1,但是方便起见这里直接直接使用curl --resolve ngx.test:8080:127.0.0.1 http://ngx.test:8080,测试如下

dongyunqi@mongodaddy:~/k8s$ curl --resolve ngx.test:8080:127.0.0.1 http://ngx.test:8080
Handling connection for 8080
srv : 1111111111110.10.1.10:80
host: ngx-dep-name-dcc8b7bfd-97x94
uri : GET ngx.test /
date: 2023-01-14T11:46:08+00:00
dongyunqi@mongodaddy:~/k8s$ curl --resolve ngx.test:8080:127.0.0.1 http://ngx.test:8080
Handling connection for 8080
srv : 1111111111110.10.1.9:80
host: ngx-dep-name-dcc8b7bfd-4v4dx
uri : GET ngx.test /
date: 2023-01-14T11:46:09+00:00

到这里就结束了。

写在后面

小结

本文分析了基于http/https七层协议来提供负载均衡的ingressingress controlleringress class并分析了每种API对象的作用并提到了ingress controller的各种实现最后给出了一个具体的实战例子。希望本文能够帮助到你。

参考文章列表

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: k8s