Ingress Controller介绍及部署实践
1. 概念
1.1 Ingress
Ingress 提供从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源所定义的规则来控制。
下面是 Ingress 的一个简单示例,可将所有流量都发送到同一 Service:
通过配置,Ingress 可为 Service 提供外部可访问的 URL、对其流量作负载均衡、 终止 SSL/TLS,以及基于名称的虚拟托管等能力。 Ingress 控制器 负责完成 Ingress 的工作,具体实现上通常会使用某个负载均衡器, 不过也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress 不会随意公开端口或协议。 将 HTTP 和 HTTPS 以外的服务开放到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。
1.2 Ingress controller
为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。Kubernetes 作为一个项目,Kubernetes 作为一个项目,目前支持和维护 AWS、 GCE 和 Nginx Ingress 控制器。此外还有一些由第三方维护的ingress contoller:
-
AKS 应用程序网关 Ingress 控制器 是一个配置 Azure 应用程序网关 的 Ingress 控制器。
-
阿里云 MSE Ingress 是一个 Ingress 控制器,它负责配置阿里云原生网关, 也是 Higress 的商业版本。
-
Apache APISIX Ingress 控制器 是一个基于 Apache APISIX 网关 的 Ingress 控制器。
-
Avi Kubernetes Operator 使用 VMware NSX Advanced Load Balancer 提供第 4 到第 7 层的负载均衡。
-
Cilium Ingress 控制器是一个由 Cilium 出品支持的 Ingress 控制器。
-
Citrix Ingress 控制器 可以用来与 Citrix Application Delivery Controller 一起使用。
-
EnRoute 是一个基于 Envoy 的 API 网关,可以用作 Ingress 控制器。
-
F5 BIG-IP 的 用于 Kubernetes 的容器 Ingress 服务 让你能够使用 Ingress 来配置 F5 BIG-IP 虚拟服务器。
-
用于 Kubernetes 的 HAProxy Ingress 控制器 也是一个针对 HAProxy 的 Ingress 控制器。
-
Istio Ingress 是一个基于 Istio 的 Ingress 控制器。
-
用于 Kubernetes 的 Kong Ingress 控制器 是一个用来驱动 Kong Gateway 的 Ingress 控制器。
-
用于 Kubernetes 的 NGINX Ingress 控制器 能够与 NGINX 网页服务器(作为代理)一起使用。
备注:nginx和k8s官方各自维护了一套 nginx ingress controller
-
Traefik Kubernetes Ingress 提供程序 是一个用于 Traefik 代理的 Ingress 控制器。
-
Voyager 是一个针对 HAProxy 的 Ingress 控制器。
2. ingress nginx简介
ingress nginx是一种使用nginx实现的ingress controller,作为K8S的反向代理和负载均衡器。Kubernetes 是容器化应用管理的事实标准。对许多企业而言,将生产工作负载迁移到 Kubernetes 会增加应用流量管理方面的挑战和复杂性。Ingress controller 能够将 Kubernetes 应用流量路由的复杂性抽象出来,并在 Kubernetes 服务和外部服务之间建立了一座桥梁。
Kubernetes Ingress Controller 的功能如下:
- 接受来自 Kubernetes 平台外部的流量,并将其负载均衡到 Kubernetes 平台内部运行的 pod(容器)
- 可管理集群内需要与集群外其他服务通信的服务的出向流量
- 使用 Kubernetes API 进行配置,以部署名为“Ingress 资源”的对象
- 监控 Kubernetes 中运行的 pod,并在服务添加或删除 pod 后自动更新负载均衡规则
版本兼容性矩阵:
Ingress-NGINX version | k8s supported version | Alpine Version | Nginx Version | Helm Chart Version |
---|---|---|---|---|
v1.10.1 | 1.29, 1.28, 1.27, 1.26 | 3.19.1 | 1.25.3 | 4.10.1* |
v1.10.0 | 1.29, 1.28, 1.27, 1.26 | 3.19.1 | 1.25.3 | 4.10.0* |
v1.9.6 | 1.29, 1.28, 1.27, 1.26, 1.25 | 3.19.0 | 1.21.6 | 4.9.1* |
v1.9.5 | 1.28, 1.27, 1.26, 1.25 | 3.18.4 | 1.21.6 | 4.9.0* |
v1.9.4 | 1.28, 1.27, 1.26, 1.25 | 3.18.4 | 1.21.6 | 4.8.3 |
v1.9.3 | 1.28, 1.27, 1.26, 1.25 | 3.18.4 | 1.21.6 | 4.8.* |
v1.9.1 | 1.28, 1.27, 1.26, 1.25 | 3.18.4 | 1.21.6 | 4.8.* |
v1.9.0 | 1.28, 1.27, 1.26, 1.25 | 3.18.2 | 1.21.6 | 4.8.* |
v1.8.4 | 1.27, 1.26, 1.25, 1.24 | 3.18.2 | 1.21.6 | 4.7.* |
v1.7.1 | 1.27, 1.26, 1.25, 1.24 | 3.17.2 | 1.21.6 | 4.6.* |
v1.6.4 | 1.26, 1.25, 1.24, 1.23 | 3.17.0 | 1.21.6 | 4.5.* |
v1.5.1 | 1.25, 1.24, 1.23 | 3.16.2 | 1.21.6 | 4.4.* |
v1.4.0 | 1.25, 1.24, 1.23, 1.22 | 3.16.2 | 1.19.10† | 4.3.0 |
v1.3.1 | 1.24, 1.23, 1.22, 1.21, 1.20 | 3.16.2 | 1.19.10† | 4.2.5 |
本文使用k8s 1.19版本,使用 ingress nginx 0.30.0版本。
3. 安装部署nginx-ingress
环境信息如下:
[root@k8s-master ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)
[root@k8s-master ~]# uname -a
Linux k8s-master 3.10.0-1160.71.1.el7.x86_64 #1 SMP Tue Jun 28 15:37:28 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
[root@k8s-master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 16d v1.19.0
k8s-node1 Ready worker 16d v1.19.0
k8s-node2 Ready worker 16d v1.19.0
[root@k8s-master ~]# helm version
version.BuildInfo{Version:"v3.6.1", GitCommit:"61d8e8c4a6f95540c15c6a65f36a6dd0a45e7a2f", GitTreeState:"clean", GoVersion:"go1.16.5"}
下载 Ingress-nginx yaml
文件:
[root@k8s-master ~]# mkdir ingress-nginx
[root@k8s-master ~]# cd ingress-nginx
[root@k8s-master ingress-nginx]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
[root@k8s-master ingress-nginx]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
[root@k8s-master ingress-nginx]# ls
mandatory.yaml service-nodeport.yaml
mandatory.yaml
下载后需要添加hostNetwork: true
,否则无法通过 K8s 节点 IP 地址绑定域名外部访问。
ingress-controller 会直接使用 K8s 物理机的 DNS 来解析域名,而不再使用 K8s 内部的 DNS 来解析域名。
mandatory.yaml
配置修改如下:
...
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
...
spec:
# wait up to five minutes for the drain of connections
# 添加 hostNetwork: true
hostNetwork: true
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
安装 Ingress-nginx:
[root@k8s-master ingress-nginx]# kubectl create -f mandatory.yaml
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRole is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRole
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
Warning: rbac.authorization.k8s.io/v1beta1 Role is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 Role
role.rbac.authorization.k8s.io/nginx-ingress-role created
Warning: rbac.authorization.k8s.io/v1beta1 RoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 RoleBinding
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRoleBinding
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
limitrange/ingress-nginx created
[root@k8s-master ingress-nginx]# kubectl create -f service-nodeport.yaml
service/ingress-nginx created
# 查看部署的资源
[root@k8s-master ingress-nginx]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.100.114.169 <none> 80:31433/TCP,443:32351/TCP 16m
[root@k8s-master ingress-nginx]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-7d4544b644-lmnkp 1/1 Running 0 17m
4. 创建实例测试 Ingress
my-nginx.yaml
配置文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx:latest
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
run: my-nginx
type: ClusterIP
ports:
- protocol: TCP
port: 8080
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: test.ingress.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 8080
创建 Deployment、service、ingress:
[root@k8s-master ingress-nginx]# kubectl create -f my-nginx.yaml
deployment.apps/my-nginx created
service/nginx-service created
ingress.networking.k8s.io/example-ingress created
nginx-ingress-controller
所在的节点与域名做好hosts
绑定,访问后端pod服务:
# 本文环境中nginx-ingress-controller容器调度到了master节点
[root@k8s-master ingress-nginx]# kubectl get pod -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-controller-7d4544b644-lmnkp 1/1 Running 0 24m 192.168.0.51 k8s-master <none> <none>
# 在其他节点上添加域名解析,域名指向nginx-ingress-controller所在节点的ip
[root@k8s-node1 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.51 test.ingress.com
# curl测试
[root@k8s-node1 ~]# curl test.ingress.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
5. 优化 Ingress-nginx部署
上述Ingress
部署为 Deployment 类型,可以优化改为 DaemonSet ,让每个工作节点运行一个 ingress-controller,实现高可用部署,避免单点故障。
...
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
selector:
...
部署daemonset:
[root@k8s-master ingress-nginx]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-9vckp 1/1 Running 0 2m48s
nginx-ingress-controller-j5dvr 1/1 Running 0 2m48s
nginx-ingress-controller-jndjr 1/1 Running 0 2m48s
备注:本文使用的k8s环境,master节点设置可调度业务容器。
改为高可用部署后,即可将域名test.ingress.com
同时解析到各节点ip,达到高可用部署的目的。
6. 参考资料
-
仓库地址:https://github.com/kubernetes/ingress-nginx
-
官网:https://kubernetes.github.io/ingress-nginx/
-
nginx官网介绍:https://www.nginx-cn.net/resources/glossary/kubernetes-ingress-controller/
-
文档:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/
-
K8s Ingress-nginx 部署和实例演示 - 神奇二进制 - 博客园 (cnblogs.com)
kubernetes.github.io/ingress-nginx/