1.為什么要有Ingress
前一篇文章[K8S系列四] K8S核心組件與核心概念(Pod、Deployment、Service)中提到了NodePort類型Service,但是NodePort類型Service有如下缺點(diǎn):
1.一個(gè)端口只能一個(gè)服務(wù)使用,根據(jù)端口劃分服務(wù),需要提前規(guī)劃好(可用端口范圍:30000~32767)
2.只支持4層負(fù)載均衡設(shè)備(Service基于IPTABLE實(shí)現(xiàn)),不能實(shí)現(xiàn)7層的負(fù)載。7層與4層簡單理解就是7層最常見就是應(yīng)用層的http,也就是url;4層是傳輸層,為tcp/udp端口。
2.Ingress與Ingress Controller
Ingress是自kubernetes1.1版本后引入的資源類型,在這個(gè)資源中我們可以去配置我們的服務(wù)路由規(guī)則,但是要真正去實(shí)現(xiàn)識(shí)別這個(gè) Ingress 并提供代理路由功能,還需要安裝一個(gè)對(duì)應(yīng)的控制器Ingress controller才能實(shí)現(xiàn)。
Ingress controller是以一種插件的形式提供,有多種實(shí)現(xiàn),例如官方維護(hù)的Ingress NGINX。Ingress controller 是部署在Kubernetes之上的Docker容器。它的Docker鏡像包含一個(gè)像Nginx或HAProxy的負(fù)載均衡器和一個(gè)控制器守護(hù)進(jìn)程??刂破魇刈o(hù)程序從Kubernetes接收所需的Ingress配置。它會(huì)生成一個(gè)Nginx或HAProxy配置文件,并重新啟動(dòng)負(fù)載平衡器進(jìn)程以使更改生效。換句話說,Ingress controller是由Kubernetes管理的負(fù)載均衡器。
3.示例
3.1 Ingress Nginx安裝
如果是在公有云上安裝Ingress Nginx,可以根據(jù)Installation Guide選擇合適的安裝方式。公有云有完善的網(wǎng)絡(luò)負(fù)載均衡,類型可以選擇LoadBalancer。
但這里是通過kubeadm自行搭建的K8S集群,所以選擇Bare-Metal方式。類型為NodePort,在集群上開一個(gè)端口(范圍為: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發(fā)生變化,所以請根具體使用的版本,調(diào)整配置。具體請參考根據(jù)Deprecated APIs Removed In 1.16: Here’s What You Need To Know。
這里配置域名為foo.mydomain.com,代理的兩個(gè)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 測試
在集群外服務(wù)器的/etc/hosts中增加一條記錄192.168.0.61 foo.mydomain.com。
分別訪問foo.mydomain.com:30434和foo.mydomain.com:30434/whoami,可以看到nginx-clusterip和whoami-clusterip的返回結(jié)果。
# 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 >nginx.org</a>.<br/>
Commercial support is available at
<a >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