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 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 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 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 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 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 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:
Namespace: default
Address: 192.168.0.62
Default backend: default-http-backend:80 ()
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:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 47m (x8 over 3h48m) nginx-ingress-controller Scheduled for sync
3.3 测试
在集群外服务器的/etc/hosts
中增加一条记录192.168.0.61 foo.mydomain.com
。
分别访问foo.mydomain.com:30434
和foo.mydomain.com:30434/whoami
,可以看到nginx-clusterip和whoami-clusterip的返回结果。
# curl foo.mydomain.com:30434
Welcome to nginx!
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
# curl foo.mydomain.com:30434/whoami
I'm whoami-deployment-8886867c8-67d4f
附录
1.nginx-clutserip.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
-------
apiVersion: v1
kind: Service
metadata:
name: nginx-clusterip
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 8080
targetPort: 80
type: ClusterIP
2. whoami-clutserip.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-deployment
labels:
app: whoami
spec:
replicas: 3
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: jwilder/whoami
ports:
- containerPort: 8000
-------------
apiVersion: v1
kind: Service
metadata:
name: whoami-clusterip
spec:
selector:
app: whoami
ports:
- protocol: TCP
port: 8080
targetPort: 8000
type: ClusterIP