集群外部的请求访问集群内应用的最佳方式:Ingress
Kubernetes 通过 Service 为 Pod 提供了统一的入口地址,并使用 NodePort 和 LoadBalance 类型的 Service 让 外部的请求 可以访问 集群内部的应用。
但是,使用 NodePort 和 LoadBalance 类型有以下缺点:
- NodePort 类型通过在每个节点上暴露一个端口作为外部访问的入口,因此当 Service 很多时,这种方式会占用集群的大量端口。
- LoadBalance 类型需要为每一个 Service 都定义一个负载均衡器,会浪费资源。
因此,Kubernetes 提供了 Ingress 域名访问应用 的方式,这也是从集群外部访问集群内应用的最佳方式。
1.Ingress 是什么
Ingress 的本质是,定义了一组从域名(或 URL)到 Service 的路由转发规则。Ingress 不会公开端口信息和所使用的协议,而是通过配置 HTTP 或 HTTPS 的路由规则,来实现从集群外部访问集群内应用的 URL 并实现负载均衡功能。
要创建和配置 Ingress 路由转发规则,则需要使用 Ingress Controller。它可以由任何具有 反向代理 功能的应用(如 Nginx 和 Haproxy)来实现。
Ingress 的工作机制如下图所示。
2.使用 Ingress Controller 创建 Ingress
下面来演示如何使用 Ingress Controller 创建 Ingress,从而实现从集群外部访问集群内部的应用。首先部署 Ingress Controller,再部署应用服务,最后创建 Ingress 的路由规则从集群外部访问集群内部的应用。
在 GitHub 上搜索 kubernetes/ingress-nginx
。🚀 https://github.com/kubernetes/ingress-nginx
🚀
ingress-nginx
is an Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer.
安装 NGINX Ingress Controller(使用 ingress-nginx
项目的官方清单)。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/baremetal/deploy.yaml
输出的信息如下:
检查 Ingress Controller Pod 是否已启动。
kubectl get pods -n ingress-nginx -o wide
检查是否能看到 NodePort 服务。
kubectl get services -n ingress-nginx
从 Ingress-NGINX 控制器 v1.0.0
版本开始,需要一个 ingressclass
对象。在默认安装中,已经创建了一个名为 nginx
的 ingressclass
对象。
kubectl get ingressclasses -n ingress-nginx
如果这只是 Ingresss-NGINX 控制器的实例,您应该在入口类中添加注释 ingressclass.kubernetes.io/is-default-class
。
kubectl annotate ingressclasses nginx ingressclass.kubernetes.io/is-default-class="true" -n ingress-nginx
🚀 在集群中,我们可以设定一个默认的 IngressClass,以便处理所有没有指定 IngressClass 的 Ingress 资源。通过将
ingressclass.kubernetes.io/is-default-class
注解的值设定为true
,来使没有设置 ingressClassName 的 Ingress 使用此默认的 IngressClass。 修改后必须新创建的 Ingress 才会默认使用。
尝试使用上一步中的 NodePort 连接 Ingress 控制器。
curl 10.107.109.133
如果您尚未配置任何后端服务,您应该会看到来自 Nginx 的 404 Not Found
。现在这样就可以了。
如果您看到 Nginx 的响应,则表明 Ingress Controller 正在运行并且您可以访问它。
部署一个小型测试应用程序(httpd
Web 服务器)来验证您的 Ingress 控制器。
创建以下 YAML 文件并将其命名为 simple-web-server-with-ingress.yaml
。
apiVersion: v1
kind: Namespace
metadata:
name: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
namespace: web
spec:
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: httpd
image: httpd:2.4.53-alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-server-service
namespace: web
spec:
selector:
app: web
ports:
- protocol: TCP
port: 5000
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-server-ingress
namespace: web
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-server-service
port:
number: 5000
部署应用程序:
kubectl apply -f simple-web-server-with-ingress.yaml
查看 Pod、Deployment、Service 和 Endpoint 的信息。
kubectl get pod,deploy,svc,ep -n web -o wide
查看创建的 Ingress。
kubectl get ingress -n web
验证您是否可以使用 NodePort 访问您的应用程序。
curl 10.107.109.133 -H 'Host: web.example.com'
如果成功,您应该看到 <html><body><h1>It Works!</h1></body></html>
。
编辑 hosts
文件加入 IP 地址与域名的对应关系,如下:
10.107.109.133 web.example.com
通过域名访问应用,如下图所示。