kubernetes上構建外部能夠訪問到的應用
標籤:kubernetes 服務發現
起因是我在安裝dashboard的時候,外部無論如何也不能夠訪問到dashboard,後面改了service也只是提供了一個內網ip,而且登陸不上。
問題:如果有一個和k8s集羣不在同一個子網的機器,它該如何訪問k8s集羣內部署的服務?
參考:
基本思想:如果雲服務商不提供負載均衡器的話,外部想要訪問只能夠使用NodePort,但是一般需要nginx再進行一次反向代理。而ingress出現後可以用ingress controller讀取集羣中的ingress規則變化,動態生成nginx配置文件並注入到nginx的Pod中。
爲什麼要部署ingress:Service NodePort是4層調度,無法直接卸載https協議,而kubernetes ingress是7層調度,可以直接卸載https回話。
實驗目標
- 實現外網到內網服務器通過ServicePort的訪問
- 實現外網到內網服務器通過Ingress的訪問
- 實現其他方式的服務發現
開始實驗
因爲我安裝了istio,先將istio注入關閉:kubectl label namespace default istio-injection=disabled --overwrite
,希望我實驗完之後記得把它弄回去。
首先配置nginx的Deployment,rc也可以
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test-nginx
labels:
app: nginx
spec:
replicas: 1
template:
metadata:
labels:
app: nginx
version: v1
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
然後是service
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
ports:
- port: 80
nodePort: 30010
selector:
app: nginx
上述節點打開container,也就是nginx的80端口,並且在service上做30010到80端口的映射。
這時候就可以在集羣內部進行訪問,集羣內部所有節點都可以通過訪問節點內網IP的30010端口訪問到nginx的服務器。公網通過直接訪問ip也可以訪問到,但是經過測試只能夠在nginx的Pod所運行的服務器上成立,也就是說其他機子是不能通過30010端口訪問到nginx服務的。
這樣子是不行的,因爲公網可能會有多個出口節點,這時候如果只有一個節點能夠訪問通,顯然不可以。雖然可以通過nginx解決,但是如果每加一條服務就加一條nginx配置的話,未免過於繁瑣。
通過搜索我發現了kubernetes中新出了ingress的機制,希望它可以幫助到我。
安裝ingress
遵循官方的安裝指南
首先執行命令kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
需要安裝metalLB作爲負載均衡器,運行kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.7.3/manifests/metallb.yaml
,裏面包含了metallb-system/controller
的deployment和metallb-system/speaker
的daemonset,以及一些service。在kubectl get po -nmetallb-system
指令下確認所有的pods都成功運行後進行下一步。
根據官方文檔的說法,或者用metallb的說法,使用configmap來配置IP池。我使用了自己的IP。(注:即使只有一個IP也要表示爲範圍的形式,不然會報錯)
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 129.204.7.185-129.204.7.185
然後執行Bare-metal-using NodePort部分的命令kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml
運行kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx
可以查看生成的pods,可以看到這時候pods成功運行。
查看運行是否成功
這時候,刪除之前的Nginx,運行kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.7.3/manifests/tutorial-2.yaml
,裏面有官方配置好的nginx鏡像和service。
運行kubectl get sertvice nginx
,如果有出現ExternalIP,則任務完成。這時候,只要訪問外部的IP的指定端口,就可以訪問到內網的服務。
真是不容易啊,中間遇到了好多的問題,感謝互聯網之神,今天又順利的解決了呢。