认识Ingress-nginx

我们先来看一下官网对于ingress的解释:

Ingress提供从集群外部到集群内服务的 HTTP 和 HTTPS 路由。流量路由由 Ingress 资源所定义的规则来控制。下面是 Ingress 的一个简单示例,可将所有流量都发送到同一 Service:

ingress-diagram

通俗的理解,我们可以将ingress理解为cloud项目里的网关,通过判断请求信息、请求路径后,转发到对应的服务内。

常见的ingress控制器有ingress-nginx、Traefik、HAProxy Ingress等等,但使用最多的还是nginx,本文也会以ingress-nginx来做演示

PS:ingress-nginx 是kubernetes社区维护的,而kubernetes-ingress 是nginx官方维护的,本文使用前者!

minikube

安装Ingress-nginx控制器

运行下面的命令进行安装

1
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

开启ingress

1
minikube addons enable ingress

通过命令 kubectl get pods -n ingress-nginx 查看,展示下面的3个Pod表示成功。

image-20240326151728730

为什么admission-create和admission-path的状态为Completed?

首先我们需要知道这两个Pods的作用:

nginx-admission-create:用来创建一个或多个admission配置,以及验证并更新kubernetes资源

ingress-nginx-admission-patch:负责更新已存在的admission配置。

这两个Pod的任务结束后就会进入Completed状态。此时任务完成,Pods结束生命,标记为Completed状态

controller是做什么的?

ingress-nginx-controller:ingress控制器实际运行的地方,具体的作用有如下2点。1:监听ingress资源,当检测到新的ingress资源或现有的ingress资源发生变动时,会同步更新内部配置;2:路由请求,会对请求进行对应的校验、然后转发到对应的Service里

使用Ingress-nginx进行请求转发

因为ingress要将请求转发到Service,所以在使用ingress进行路由时,首先需要确保已经创建了对应Pods和Service并且正常运行,已经正常创建的可以跳转到第3步直接创建ingress

  1. 创建Deployment

    创建Deployment,副本片为2,使用我自己的一个boot项目

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: boot-deployment
    spec:
    replicas: 2
    selector:
    matchLabels:
    app: sora-boot
    template:
    metadata:
    labels:
    app: sora-boot
    spec:
    containers:
    - name: sora
    image: sora33/k8s:v2.0

    执行命令 kubectl apply -f ${文件名) 来完成Deployment的创建

  2. 创建Service

    定义Service的名字,绑定标签为sora-boot的Pods,同时映射端口信息,配置负载均衡方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    apiVersion: v1
    kind: Service
    metadata:
    name: sora-boot-service
    spec:
    selector:
    app: sora-boot
    ports:
    - protocol: TCP
    name : sora-boot
    port: 1234
    targetPort: 1234
    type: LoadBalancer

    继续创建一个Service

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    apiVersion: v1
    kind: Service
    metadata:
    name: sora-boot-service2
    spec:
    selector:
    app: sora-boot
    ports:
    - protocol: TCP
    name : sora-boot
    port: 1234
    targetPort: 1234
    type: LoadBalancer

    执行命令 kubectl apply -f ${文件名) 来完成Service的创建

  3. 创建Ingress

    metadata:定义ingress的名字,同时通过nginx.ingress.kubernetes.io/rewrite-target重写路径,将$1($1是正则表达式的捕获组引用,值对应path的(.*))作为路径转发到后端。例如现在我的请求路径是/boot/async/work1,那么会将该路径重写为/async/work1,同时转发到名为sora-boot-service的Service里。

    spec:指定ingressClassName控制器为nginx,下面是rules,也就是路由规则列表。

    ​ host:指定域名,只有匹配该值时,才进入规则。值是域名,所以我们需要提前设置好一个测试域名,修改我们本地的hosts文件就可以,具体路径为/etc/hosts

    ​ 如下,添加一个测试域名,并指向本机(注意:这里linux和mac不一样,linux需要设置为minikube的ip!!!mac直接设置为127.0.0.1)

    image-20240326160015312

    image-20240326155247476

    ​ path:匹配路径,下图为匹配到以boot开头的请求转发到sora-boot-service服务,boot2开头的请求转发到sora-boot-service2服务,并指定对应的端口号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: sora-ingress
    annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    spec:
    ingressClassName: nginx
    rules:
    - host: www.test33.com
    http:
    paths:
    - path: /boot/(.*)
    pathType: Prefix
    backend:
    service:
    name: sora-boot-service
    port:
    number: 1234
    - path: /boot2/(.*)
    pathType: Prefix
    backend:
    service:
    name: sora-boot-service2
    port:
    number: 1234

    执行命令 kubectl apply -f ${文件名) 来完成ingress的创建

  4. 查看ingress

创建完成后,我们来查看ingress的信息,使用下面的命令启动K8s控制台

1
minikube dashboard

我们可以看到ingress的class名字,以及规则对应的路径,匹配类型以及路由到的具体服务

image-20240326155420684

注意:下面的部分,mac因为网络的原因,需要额外开启一个终端页面启用隧道(注意输入密码)

1
minikube tunnel

image-20240326160244570

最后我们来通过ingress访问项目,请求前缀分别为boot和boot2,这里因为两个Service实际指向的都是标签为sora-boot的Pods,所以输出会一样,可以自己再创建一个不同的Pod来测试

image-20240326155549994

Kuboard

通过Kuboard可视化集群管理工具,我们可以通过页面创建并更新容器。通过Kuboard创建之前我希望可以看一下上面minikube的流程,因为实际上底层是一样的,并且上面也解答了很多原理性的东西~

安装Ingress-nginx控制器

集群管理菜单中选择网络,点击安装、输入一个Ingress名称,副本数可以自己按需求设定。

image-20240403140932907

点击我们创建好的Ingress名称进入管理页面,可以看到目前Pods都已就绪

image-20240403141120303

这里注意看顶部,会提示我们配置2个端口转发,这里很重要,如果不配置,Ingress会无法使用!

image-20240403141158738

这里需要通过nginx实现,所以需要下载一个nginx。nginx的下载可参考我之前的一个文章:nginx下载 (这里我们安装在任意一个子节点上即可!!!不能安装在master节点!)

安装完成后修改/usr/local/nginx/conf下的nginx.conf文件。需要在http模块下加入2个server,注意默认会有一个监听80的端口,我们只需要在此基础上改就可以,注意将对应的80和443改为Ingress页面给你提示的端口号。然后进入/usr/local/nginx.sbin 通过 ./nginx 启动nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
server {
listen 80;
server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
# root html;
# index index.html index.htm;
proxy_pass http://localhost:30668;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
server {
listen 443;
server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
# root html;
# index index.html index.htm;
proxy_pass http://localhost:32403;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

使用Ingress-nginx进行请求转发

创建两个负载

因为我们需要测试Ingress的流量转发,所以需要2个完全不同的容器。如图,我用了一个nginx容器和一个portainer容器来测试

image-20240403142639793

如果刚开始用Kuboard不知道如何创建的话,这里我创建一个Deployment来演示一下:

选择一个命名空间,创建工作负载,类型从DeploymentStatefulSet选择一个就可以。一般无状态应用选择前者,有状态则选择后者。输入负载名称,调整副本数。

image-20240403142928541

在容器信息页面输入镜像名,注意这里是镜像名!!!选择策略并映射端口号,将容器的80映射到宿主机的32002端口上。宿主机的端口范围30000-32767

image-20240403143054130

完成后点击上方保存,接着同样创建第二个负载,可以使用portainer/portainer这个镜像,这是一个监控docker的开源工具

开启服务

进入工作负载,点击编辑,我们勾选服务,如下配置服务的端口为80,对应容器的80端口,同时工作端口为30883。

image-20240403143809543

之后同样为另一个负载也开启服务

开启路由

在开启路由前,首先我们需要配置自己的域名,这里我用 www.test33.com 当然你也可以自定义名字

1
2
# 编辑hosts
vim /etc/hosts

image-20240403145535170

回到之前开启服务的页面,继续勾选服务下方的路由,配置如下,域名输入我们刚刚配置的域名,配置前缀为/nginx开头的请求,将其转发到nginx负载的80端口上

image-20240403145253190

之后同样为另一个负载也开启路由

访问测试

现在我们通过域名+前缀匹配的方式测试Ingress是否生效,如下图,都成功进入对应的主页

nginx:

image-20240403145730737

portainer:

image-20240403145821733