1. kube-proxy 只容許本地訪問node
2. NodePort 使用物理機端口和k8s service虛擬ip:端口 映射nginx
3. LoadBalancer 使用NodeIp+Nodeport的方式實現, 配合雲環境GCE、aws提供的負載地址數據庫
4. ingress 使用開源的反向代理負載均衡器來實現對外暴漏服務,好比 Nginx、Apache、Haproxy後端
做者:莫逐負載均衡(LB)在微服務架構演進中具備很是重要的意義,能夠說的內容有不少,這裏僅僅討論四層和七層負載均衡的一些要點和區別,以便於對ingress的理解。所謂四層和七層負載均衡是按照網絡層次OSI來劃分的負載均衡類型(也能夠按照其餘的規則來分類,好比:應用的地理結構),簡單來講:四層負載均衡表示負載均衡器用ip+port接收請求,再直接轉發到後端對應的服務上,工做在傳輸層( transport layer );七層負載均衡表示負載均衡器根據虛擬的url或主機名來接收請求,通過處理後再轉向相應的後端服務上,工做在應用層( application layer )。api
下圖表示了4層和7層負載均衡在創建TCP鏈接上的區別,從圖中能夠看出,四層負載均衡須要創建的TCP鏈接其實之有一個,它只作一次轉發,client直接和server鏈接;而7層負載均衡則須要創建兩次TCP鏈接,client到LB,LB根據消息中的內容( 好比URL或者cookie中的信息 )來作出負載均衡的決定,接着創建LB到server的鏈接。瀏覽器
layer4VSlayer7_LB.pngbash
7層負載均衡有什麼好處呢?服務器
舉個例子:
正向代理:在使用VPS訪問的時候,一般會使用一個本地的代理服務器,瀏覽器的網絡包會先通過本地的代理服務器,代理服務器會經過遠在異國它鄉的電腦來訪問並返回消息;這就比如去附近的咖啡店要先問一下手機咖啡店在哪裏同樣,手機就是一個正向代理服務器。
反向代理:當訪問的請求到達時,那邊也設置了一個代理服務器,它經過查看請求的URL,發現是想查找視頻內容,於時把消息轉給了視頻搜索服務器(過程是我亂說的),這就比如你去朋友家作客,開門的倒是個管家,問你找誰?這時候管家就是一個反向代理了。cookie
其餘OSI層也能夠作反向代理網絡
k8s 對外暴露服務(service)主要有兩種方式:NotePort, LoadBalance, 此外externalIPs也可使各種service對外提供服務,可是當集羣服務不少的時候,NodePort方式最大的缺點是會佔用不少集羣機器的端口;LB方式最大的缺點則是每一個service一個LB又有點浪費和麻煩,而且須要k8s以外的支持; 而ingress則只須要一個NodePort或者一個LB就能夠知足全部service對外服務的需求。工做機制大體能夠用下圖表示:
實際上,ingress至關於一個7層的負載均衡器,是k8s對反向代理的一個抽象。大概的工做原理也確實相似於Nginx,能夠理解成在 Ingress 裏創建一個個映射規則 , ingress Controller 經過監聽 Ingress這個api對象裏的配置規則並轉化成 Nginx 的配置(kubernetes聲明式API和控制循環) , 而後對外部提供服務。ingress包括:ingress controller和ingress resources
ingress controller:核心是一個deployment,實現方式有不少,好比nginx, Contour, Haproxy, trafik, Istio,須要編寫的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的類型能夠是NodePort或者LoadBalancer。
ingress resources:這個就是一個類型爲Ingress的k8s api對象了,這部分則是面向開發人員。
使用 Ingress 對外暴露服務
爲了快速體驗 Ingress,下面部署一個 nginx 服務,而後經過 Ingress 對外暴露 nginx service 進行訪問。
首先部署 nginx 服務:
Deployment + Service:nginx.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
kubectl create -f nginx.yml
接下來建立 Ingress 對外暴露 nginx service 80 端口:
ingress.yml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: nginx.kube.com
http:
paths:
- path: /
backend:
serviceName: nginx
servicePort: 80
說明:
kubernetes.io/ingress.class: "nginx":Nginx Ingress Controller 根據該註解自動發現 Ingress;
host: nginx.kube.com:對外訪問的域名;
serviceName: nginx:對外暴露的 Service 名稱;
servicePort: 80:nginx service 監聽的端口;
注意:建立的 Ingress 必需要和對外暴露的 Service 在同一命名空間下!
將域名 nginx.kube.com 綁定到 k8s 任意節點 ip 便可訪問:http://nginx.kube.com
上面的示例不支持 https 訪問,下面舉一個支持 https 的 Ingress 例子:經過 Ingress 訪問 kubernetes dashboard 服務。
經過 Ingress 訪問 kubernetes dashboard(支持 HTTPS 訪問)
以前咱們使用 helm 以 nodePort 的方式部署了 kubernetes dashboard:「helm 部署 kubernetes-dashboard」,從集羣外部只能經過 nodeIP:nodePort 端口號 訪問,接下來基於以前部署的 kubernetes-dashboard 配置如何經過 Ingress 訪問,而且支持 HTTPS 訪問,HTTP 自動跳轉到 HTTPS。 :
首先,練習使用,先用自簽名證書來代替吧:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout kube-dashboard.key -out kube-dashboard.crt -subj "/CN=dashboard.kube.com/O=dashboard.kube.com"
使用生成的證書建立 k8s Secret 資源,下一步建立的 Ingress 會引用這個 Secret:
kubectl create secret tls kube-dasboard-ssl --key kube-dashboard.key --cert kube-dashboard.crt -n kube-system
建立 Ingress 資源對象(支持 HTTPS 訪問):
kube-dashboard-ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-kube-dashboard
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
tls:
- hosts:
- dashboard.kube.com
secretName: kube-dasboard-ssl
rules:
- host: dashboard.kube.com
http:
paths:
- path: /
backend:
serviceName: kubernetes-dashboard
servicePort: 443
kubectl create -f kube-dashboard-ingress.yml -n kube-system
說明:
kubernetes.io/ingress.class: "nginx":Inginx Ingress Controller 根據該註解自動發現 Ingress;
nginx.ingress.kubernetes.io/backend-protocol: Controller 向後端 Service 轉發時使用 HTTPS 協議,這個註解必須添加,不然訪問會報錯,能夠看到 Ingress Controller 報錯日誌:kubectl logs -f nginx-ingress-controller-mg8df
2019/08/12 06:40:00 [error] 557#557: *56049 upstream sent no valid HTTP/1.0 header while reading response header from upstream, client: 192.168.26.10, server: dashboard.kube.com, request: 「GET / HTTP/1.1」, upstream: 「http://10.244.1.8:8443/」, host: 「dashboard.kube.com」
報錯緣由主要是 dashboard 服務後端只支持 https,可是 Ingress Controller 接到客戶端的請求時日後端 dashboard 服務轉發時使用的是 http 協議,解決辦法就是給 建立的 Ingress 設置:nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" 註解。解決方法參考自 StackOverflow:https://stackoverflow.com/questions/48324760/ingress-configuration-for-dashboard
secretName: kube-dasboard-ssl:https 證書 Secret;
host: dashboard.kube.com:對外訪問的域名;
serviceName: kubernetes-dashboard:集羣對外暴露的 Service 名稱;
servicePort: 443:service 監聽的端口;
注意:建立的 Ingress 必需要和對外暴露的 Service 在同一命名空間下!
將域名 dashboard.kube.com 綁定到 k8s 任意節點 ip 便可訪問:https://dashboard.kube.com
負載均衡(LB)在微服務架構演進中具備很是重要的意義,能夠說的內容有不少,這裏僅僅討論四層和七層負載均衡的一些要點和區別,以便於對ingress
的理解。所謂四層和七層負載均衡是按照網絡層次OSI來劃分的負載均衡類型(也能夠按照其餘的規則來分類,好比:應用的地理結構),簡單來講:四層負載均衡
表示負載均衡器用ip+port接收請求,再直接轉發到後端對應的服務上,工做在傳輸層( transport layer );七層負載均衡
表示負載均衡器根據虛擬的url或主機名來接收請求,通過處理後再轉向相應的後端服務上,工做在應用層( application layer )。
下圖表示了4層和7層負載均衡在創建TCP鏈接上的區別,從圖中能夠看出,四層負載均衡須要創建的TCP鏈接其實之有一個,它只作一次轉發,client直接和server鏈接;而7層負載均衡則須要創建兩次TCP鏈接,client到LB,LB根據消息中的內容( 好比URL或者cookie中的信息 )來作出負載均衡的決定,接着創建LB到server的鏈接。
7層負載均衡有什麼好處呢?
舉個例子:
正向代理
:在使用VPS訪問的時候,一般會使用一個本地的代理服務器,瀏覽器的網絡包會先通過本地的代理服務器,代理服務器會經過遠在異國它鄉的電腦來訪問並返回消息;這就比如去附近的咖啡店要先問一下手機咖啡店在哪裏同樣,手機就是一個正向代理服務器。
反向代理
:當訪問的請求到達時,那邊也設置了一個代理服務器,它經過查看請求的URL,發現是想查找視頻內容,於時把消息轉給了視頻搜索服務器(過程是我亂說的),這就比如你去朋友家作客,開門的倒是個管家,問你找誰?這時候管家就是一個反向代理了。
關於反向代理的好處這裏就很少介紹,感興趣能夠看這裏
其餘OSI層也能夠作反向代理
k8s 對外暴露服務(service)主要有兩種方式:NotePort
, LoadBalance
, 此外externalIPs
也可使各種service對外提供服務,可是當集羣服務不少的時候,NodePort方式最大的缺點是會佔用不少集羣機器的端口;LB方式最大的缺點則是每一個service一個LB又有點浪費和麻煩,而且須要k8s以外的支持; 而ingress則只須要一個NodePort或者一個LB就能夠知足全部service
對外服務的需求。工做機制大體能夠用下圖表示:
實際上,ingress
至關於一個7層的負載均衡器,是k8s對反向代理的一個抽象。大概的工做原理也確實相似於Nginx,能夠理解成在 Ingress 裏創建一個個映射規則 , ingress Controller
經過監聽 Ingress
這個api對象裏的配置規則並轉化成 Nginx 的配置(kubernetes聲明式API和控制循環) , 而後對外部提供服務。ingress包括:ingress controller和ingress resources
ingress controller
:核心是一個deployment,實現方式有不少,好比nginx, Contour, Haproxy, trafik, Istio,須要編寫的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的類型能夠是NodePort或者LoadBalancer。
ingress resources
:這個就是一個類型爲Ingress
的k8s api對象了,這部分則是面向開發人員。
假設已經有兩個服務部署在了k8s集羣內部:
$ kubectl get svc,deploy NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc/coffee-svc ClusterIP <none> <none> 80/TCP 1m svc/tea-svc ClusterIP <none> <none> 80/TCP 1m NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deploy/coffee 2 2 2 2 1m deploy/tea 1 1 1 1 1m做者:MunCN
對外服務方式
1. kube-proxy 只容許本地訪問
2. NodePort 使用物理機端口和k8s service虛擬ip:端口 映射
3. LoadBalancer 使用NodeIp+Nodeport的方式實現, 配合雲環境GCE、aws提供的負載地址
4. ingress 使用開源的反向代理負載均衡器來實現對外暴漏服務,好比 Nginx、Apache、Haproxy等
做者:莫逐對外服務方式
1. kube-proxy 只容許本地訪問
2. NodePort 使用物理機端口和k8s service虛擬ip:端口 映射
3. LoadBalancer 使用NodeIp+Nodeport的方式實現, 配合雲環境GCE、aws提供的負載地址
4. ingress 使用開源的反向代理負載均衡器來實現對外暴漏服務,好比 Nginx、Apache、Haproxy等
做者:莫逐