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
---- ------ ---- ---- -------
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
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
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>
# 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