由于最近服务迁移,进行了各种调整,调整的过程中也顺便修改了 ingress 的相关配置,发现这块之前没有写过,于是今天就来看看 ingress 的基本使用。

其实 ingress 本身不复杂,只要理解了概念,很快就能上手。

PS:本文需要前置知识点 kubernetes 的 service

什么是 ingress

如果用一句话总结什么是 ingress,那我觉得:ingress 就是 service 的 service

其实 ingress 就是在 service 之前再加入了一层网关/路由,根据配置的不同规则,将请求路由到不同的 service 中,然后对外集群只暴露一个访问的地方

为什么需要 ingress

在 k8s 集群中,我们知道,想要暴露一个 deployment 那么就需要创建一个 service,这个 service 会帮助我们路由到多个 pod 上。但 service 想要被外部访问,有下面几种方式:

  • ClusterIP 只能内部访问
  • NodePort 需要占用端口,当服务数量多,管理麻烦
  • LoadBalance 要么自己用轮子(metallb)也会占用端口,要么你已经上云了,直接用云厂商的
  • Port Forwarding 临时测试用的

总之,想要我们的服务暴露在公网上,势必要将 service 暴露出去,而使用 NodePort 占用端口的方式也有所不足,并且整个 k8s 维护着成百上千个服务,管理也很麻烦。

在没有使用 ingress 的时候

即使你不使用 ingress 你往往不可能将一个域名 dns 指向一个 ip 之后就不管了。

比如将 linkinstars.com -> 1.1.1.1 ,如果只是这样,那么你就只有一个服务,你大可不必整个集群。既然上了 k8s 往往服务数量就很多,势必会有下面这样的情况

所以在没有 ingress 的时候,你需要在整个集群之前在放一个网关,比如 nginx,将不同的域名指向不同的 ip

其实

所以其实 ingress 也没有你想的那么复杂,它就只是替代了原本最外层的网关而已,只不过这个网关直接交由 k8s 进行管理了。

PS: 当然有的大厂 ingress 前面依然有其他的网关产品,这个根据实际情况自行判断。

这样你在 dns 域名配置的时候只需要将 域名 指向你 ingress 暴露的 ip 就可以了

概念

首先我们需要认识两个概念:ingressingress-controller,你可以简单这样理解:

  • ingress-controller 是反向代理程序
  • ingress 是反向代理规则

ingress-controller

ingress-controller 是 ingress 中核心的组件,就是这个控制器来进行具体的转发和路由,外部的流量最先到达的就是它,它会根据你具体配置的规则来进行请求转发。

当然 ingress-controller 有着各种各样的实现,k8s 官方维护的实现就是 ingress-nginx。

ingress

ingress 其实是 k8s 中的一个对象,和 deployment 、service 一样,而它的功能就是去定义具体的转发规则,这些配置的规则的变化会被监控,并将这些规则给到 ingress-controller

以 ingress-nginx 部署为例

这里以官方的 ingress-nginx 为例来看看具体使用

ingress-nginx 的部署

部署非常简单,一个命令基本就可以,如果喜欢用 helm 也可以

https://kubernetes.github.io/ingress-nginx/deploy/#quick-start

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

ingress-nginx-controller 修改配置

ingress-nginx 安装完成之后会在 ingress-nginx 命名空间下,在该命名空间下的 service 中找到 ingress-nginx-controller,默认类型应该是个 LoadBalancer,你可以根据你自己的需要进行修改,无论是使用 lb 还是 NodePort,总之需要暴露给外网即可。

ingress 的配置

比如我们想将 api.linkinstars.com/user 转发到 user 的 service 的 8080 端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: your-namespace
name: ingress-test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx # 注意这里的名称来源于命令 kubectl get ingressclass,根据你具体使用的 ingress 有关
rules:
- host: api.linkinstars.com
http:
paths:
- path: /user
pathType: Prefix
backend:
service:
name: user
port:
number: 8080

ingress 的其他具体配置可以参考官方文档

总结

其实 ingress 理解很简单,以 ingress-nginx 为例,整个过程就是:

  1. ingress-controller 通过 APIServer 获取 ingress 资源的变化
  2. 当 ingress 资源变化时,重新生成路由规则 nginx.conf
  3. 然后重新加载这个规则 nginx -s reload
  4. 当流量打到 ingress-controller 的时候,根据具体规则路由即可

当然这只是 ingress 的简单使用,往往等集群大了之后,可能会有多个 ingress,并且他们之间的变动可能会“打架”,那么这部分就放到后面再说趴。

参考链接

其他

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=37kt4vrf6jok0