原文:https://www.jianshu.com/p/cd7ebd6876c9
1.为什么要有Ingress
前一篇文章[K8S系列四] K8S核心组件与核心概念(Pod、Deployment、Service)中提到了NodePort类型Service,但是NodePort类型Service有如下缺点:
1.一个端口只能一个服务使用,根据端口划分服务,需要提前规划好(可用端口范围:30000~32767)
2.只支持4层负载均衡设备(Service基于IPTABLE实现),不能实现7层的负载。7层与4层简单理解就是7层最常见就是应用层的http,也就是url;4层是传输层,为tcp/udp端口。
2.Ingress与Ingress Controller
Ingress是自kubernetes1.1版本后引入的资源类型,在这个资源中我们可以去配置我们的服务路由规则,但是要真正去实现识别这个 Ingress 并提供代理路由功能,还需要安装一个对应的控制器Ingress controller才能实现。
Ingress controller是以一种插件的形式提供,有多种实现,例如官方维护的Ingress NGINX。Ingress controller 是部署在Kubernetes之上的Docker容器。它的Docker镜像包含一个像Nginx或HAProxy的负载均衡器和一个控制器守护进程。控制器守护程序从Kubernetes接收所需的Ingress配置。它会生成一个Nginx或HAProxy配置文件,并重新启动负载平衡器进程以使更改生效。换句话说,Ingress controller是由Kubernetes管理的负载均衡器。
3.示例
3.1 Ingress Nginx安装
如果是在公有云上安装Ingress Nginx,可以根据Installation Guide选择合适的安装方式。公有云有完善的网络负载均衡,类型可以选择LoadBalancer
。
但这里是通过kubeadm自行搭建的K8S集群,所以选择Bare-Metal方式。类型为NodePort,在集群上开一个端口(范围为:30000-32767),用于简单测试。
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/baremetal/deploy.yaml
# kubectl get svc -o wide -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
default-http-backend ClusterIP 10.111.34.218 <none> 80/TCP 3h40m app.kubernetes.io/name=default-http-backend,app.kubernetes.io/part-of=ingress-nginx
ingress-nginx-controller NodePort 10.108.187.49 <none> 80:30434/TCP,443:30609/TCP 178m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
ingress-nginx-controller-admission ClusterIP 10.102.128.23 <none> 443/TCP 178m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
3.2 配置ingress
需要注意从1.16开始,部分api发生变化,所以请根具体使用的版本,调整配置。具体请参考根据Deprecated APIs Removed In 1.16: Here’s What You Need To Know。
这里配置域名为foo.mydomain.com,代理的两个Service为nginx-clusterip和whoami-cluster。nginx-clusterip和whoami-cluster的yaml配置请参考附录1和2
#ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
ingressClassName: nginx
rules:
- host: foo.mydomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-clusterip
port:
number: 8080
- path: /whoami
pathType: Prefix
backend:
service:
name: whoami-clusterip
port:
number: 8080
# kubectl apply -f ingress.yaml
# kubectl get svc -o wide -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
default-http-backend ClusterIP 10.111.34.218 <none> 80/TCP 5h15m app.kubernetes.io/name=default-http-backend,app.kubernetes.io/part-of=ingress-nginx
ingress-nginx-controller NodePort 10.108.187.49 <none> 80:30434/TCP,443:30609/TCP 4h33m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
ingress-nginx-controller-admission ClusterIP 10.102.128.23 <none> 443/TCP 4h33m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ingress nginx foo.mydomain.com 192.168.0.62 80 3h47m
# kubectl describe ingress nginx-ingress
Name: nginx-ingress
Labels: <none>
Namespace: default
Address: 192.168.0.62
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
foo.mydomain.com
/ nginx-clusterip:8080 (10.244.190.84:80,10.244.190.85:80,10.244.190.86:80 + 1 more...)
/whoami whoami-clusterip:8080 (10.244.190.88:8000,10.244.80.211:8000,10.244.80.212:8000)
Annotations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------