2.4、Ingress
我們前面介紹過用Service做集群代理,Service一般情況下只作用于內部Pod的代理調度,就算有NodePort類型觉既,其訪問節(jié)點相對復雜,流程大概如下:
<br />但是我們知道乳幸,如果只指定一個NodeIP瞪讼,隨著業(yè)務量增大,這個Node的壓力就會很大粹断,所以我們可能會在前端再加一個代理符欠,代理幾個Node,比如我們在前端加一個NG瓶埋,流程如下:
在應用小的情況下希柿,這種架構雖然調度復雜诊沪,但是也可以使用,但是如果有大量應用曾撤,這種管理就非常麻煩端姚,因為 我們要管理大量的NodePort,這個時候使用Ingress就非常方便挤悉。
再則渐裸,Service的轉發(fā)不論是iptables還是ipvs,都是4層的尖啡,但是在實際中基本都https請求橄仆,https是7層剩膘,4層是沒辦法對起進行SSL校驗的衅斩,如果我們是第二幅流程圖,我們可以在前置NG上配置SSL怠褐,但是如果我們是第一幅圖的流程畏梆,我們只能在Pod上配置SSL,因為Service上是無法進行校驗奈懒,那么就會出現一個問題奠涌,SSL的校驗是很耗資源的,我們的客戶端訪問Pod磷杏,如果Pod非常多并且訪問模式是輪詢溜畅,那么每訪問一次就要做一次SSL校驗,這就非常不科學极祸,我們就只有用類似于第二副圖的架構慈格,Ingress可以很完美的解決這種問題。
一遥金、Ingress
流程圖如上浴捆,其中Ingress代理的并不是Pod的Service,而是Pod稿械,之所以在配置的時候是配置的Service选泻,是為了獲取Pod的信息。
Ingress提供外部訪問集群的入口美莫,將外部的HTTP或者HTTPS請求轉發(fā)到集群內Service上页眯,流量規(guī)則是在Ingress資源上定義。<br />配置Ingress資源的必要條件是你的kubernetes集群種由Ingress controller厢呵。其中Ingress Controller常用的有如下:
- HAProxy Ingress Controller
- Nginx Ingress Controller
- Traefik Ingress Controller
- Kong Ingress Controller
其中最常用的是Nginx Controller和Traefik Ingress Controller窝撵。<br />定義一個簡單的Ingresss:
[root@master ingress]# cat ingress-simple-daemo.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-simple-daemo
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /joker
backend:
serviceName: nginx
servicePort: 80
簡要說明:<br />apiVersion,kind述吸,metadata忿族,spec都是Kubernetes YAML文件的標準字段锣笨,Ingress經常通過annotations來配置一些選項,比如rewrite-target道批,不同的Ingress Controller支持不同的annotations错英。對于規(guī)則而言,每個HTTP都有如下規(guī)則:
- 主機:主機是可選參數隆豹,如果不配置表示適用于所有主機HTTP通信椭岩,如果配置了表示只適用于該主機;
- 路徑:類似于NG的location璃赡,每個路徑后面都有后端ServiceName和ServicePort判哥;
- 后端:后端是ServiceName和ServicePort組合,符合該規(guī)則的流量會轉發(fā)到這個后端Service上碉考。通常會在Ingress中配置默認后端塌计,以匹配任何不符合規(guī)則的請求流量轉發(fā);
- 具體的語法規(guī)則可以通過kubectl explain ingress來查看侯谁。
1.1锌仅、Ingress 類型
1.1.1、單服務Ingress
Kubernetes中已經存在一些概念可以暴露單個service(查看替代方案)墙贱,但是你仍然可以通過Ingress來實現热芹,通過指定一個沒有rule的默認backend的方式。比如:
[root@master ingress]# cat single-service-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: single-service-ingress
spec:
backend:
serviceName: nginx
servicePort: 80
1.1.2惨撇、簡單展開
如前面描述的那樣伊脓,kubernete pod中的IP只在集群網絡內部可見,我們需要在邊界設置一個東西魁衙,讓它能夠接收ingress的流量并將它們轉發(fā)到正確的端點上报腔。這個東西一般是高可用的loadbalancer。使用Ingress能夠允許你將loadbalancer的個數降低到最少纺棺,例如榄笙,假如你想要創(chuàng)建這樣的一個設置:
foo.bar.com -> 178.91.123.132 -> / foo service1:4200
/ bar service2:8080
我們就可以這樣配置Ingress:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 4200
- path: /bar
backend:
serviceName: service2
servicePort: 8080
1.1.3、基于名稱的虛擬主機
如果想實現下面這種需求:
foo.bar.com --| |-> foo.bar.com s1:80
| 178.91.123.132 |
bar.foo.com --| |-> bar.foo.com s2:80
我們就可以這樣配置Ingress:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
如果要增加配置默認的backend祷蝌,可以配置成如下Ingress:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: first.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: second.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
- http:
paths:
- backend:
serviceName: service3
servicePort: 80
默認backend:一個沒有rule的ingress茅撞,所有流量都將發(fā)送到一個默認backend。你可以用該技巧通知loadbalancer如何找到你網站的404頁面巨朦,通過制定一些列rule和一個默認backend的方式米丘。如果請求header中的host不能跟ingress中的host匹配,并且/或請求的URL不能與任何一個path匹配糊啡,則流量將路由到你的默認backend拄查。
1.1.4、TLS
你可以通過指定包含TLS私鑰和證書的secret來加密Ingress棚蓄。 目前堕扶,Ingress僅支持單個TLS端口443碍脏,并假定TLS termination。 如果Ingress中的TLS配置部分指定了不同的主機稍算,則它們將根據通過SNI TLS擴展指定的主機名(假如Ingress controller支持SNI)在多個相同端口上進行復用典尾。 TLS secret中必須包含名為tls.crt
和tls.key
的密鑰,這里面包含了用于TLS的證書和私鑰糊探,例如:
apiVersion: v1
kind: Secret
metadata:
name: testsecret-tls
namespace: default
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
type: kubernetes.io/tls
在Ingress中引用這個secret將通知Ingress controller使用TLS加密從將客戶端到loadbalancer的channel:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- sslexample.foo.com
secretName: testsecret-tls
rules:
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
注意:各種Ingress controller支持的TLS功能之間存在差距钾埂。 請參閱有關nginx,GCE或任何其他平臺特定Ingress controller的文檔科平,以了解TLS在你的環(huán)境中的工作原理褥紫。
1.2、Ingress更新
如果你想更改你現在正工作的Ingress瞪慧,比如新增一個HOST髓考,可以使用kubectl edit ingress my-ingress進行更新,在保存退出后其會觸發(fā)Ingress Controller重新配置LB汞贸。比如我們現有一個ingress:
[root@master ingress]# kubectl get ingresses.
NAME HOSTS ADDRESS PORTS AGE
* 80 58m
然后我們使用kubectl edit ingress ingress-simple-daemo來新增一個HOST:
......
spec:
rules:
- http:
paths:
- backend:
serviceName: nginx-service
servicePort: 8000
path: /joker
- host: bar.baz.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
path: /foo
status:
loadBalancer: {}
保存退出后就會生效:
[root@master ingress]# kubectl describe ingresses ingress-simple-daemo
Name: ingress-simple-daemo
Namespace: default
Address:
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
*
/joker nginx-service:8000 (172.20.2.84:80)
bar.baz.com
/foo nginx:80 (172.20.2.79:80,172.20.2.82:80)
Annotations:
kubernetes.io/ingress.class: traefik
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"traefik"},"name":"ingress-simple-daemo","namespace":"default"},"spec":{"rules":[{"http":{"paths":[{"backend":{"serviceName":"nginx-service","servicePort":8000},"path":"/joker"}]}}]}}
Events: <none>
參考文檔:https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
-----------------------
公眾號:喬邊故事(ID:qiaobiangushi)
知乎: 喬邊故事
頭條號:喬邊故事
只要臉皮夠厚绳军,整個世界都將被你踩在腳下印机。
-----------------------