Kubernetes 系列(三):Kubernetes使用Traefik Ingress暴露服务
一、Kubernetes 服務暴露介紹
從 kubernetes 1.2 版本開始,kubernetes提供了 Ingress 對象來實現對外暴露服務;到目前為止 kubernetes 總共有三種暴露服務的方式:
- LoadBlancer Service
- NodePort Service
- Ingress
1.1、LoadBlancer Service
LoadBlancer Service 是 kubernetes 深度結合云平臺的一個組件;當使用 LoadBlancer Service 暴露服務時,實際上是通過向底層云平臺申請創建一個負載均衡器來向外暴露服務;目前 LoadBlancer Service 支持的云平臺已經相對完善,比如國外的 GCE、DigitalOcean,國內的 阿里云,私有云 Openstack 等等,由于 LoadBlancer Service 深度結合了云平臺,所以只能在一些云平臺上來使用
1.2、NodePort Service
NodePort Service 顧名思義,實質上就是通過在集群的每個 node 上暴露一個端口,然后將這個端口映射到某個具體的 service 來實現的,雖然每個 node 的端口有很多(0~65535),但是由于安全性和易用性(服務多了就亂了,還有端口沖突問題)實際使用可能并不多
1.3、Ingress
Ingress 這個東西是 1.2 后才出現的,通過 Ingress 用戶可以實現使用 nginx 等開源的反向代理負載均衡器實現對外暴露服務,以下詳細說一下 Ingress,畢竟 traefik 用的就是 Ingress
使用 Ingress 時一般會有三個組件:
- 反向代理負載均衡器
- Ingress Controller
- Ingress
1.3.1、反向代理負載均衡器
反向代理負載均衡器很簡單,說白了就是 nginx、apache 什么的;在集群中反向代理負載均衡器可以自由部署,可以使用 Replication Controller、Deployment、DaemonSet 等等,不過個人喜歡以 DaemonSet 的方式部署,感覺比較方便
1.3.2、Ingress Controller
Ingress Controller 實質上可以理解為是個監視器,Ingress Controller 通過不斷地跟 kubernetes API 打交道,實時的感知后端 service、pod 等變化,比如新增和減少 pod,service 增加與減少等;當得到這些變化信息后,Ingress Controller 再結合下文的 Ingress 生成配置,然后更新反向代理負載均衡器,并刷新其配置,達到服務發現的作用
1.3.3、Ingress
Ingress 簡單理解就是個規則定義;比如說某個域名對應某個 service,即當某個域名的請求進來時轉發給某個 service;這個規則將與 Ingress Controller 結合,然后 Ingress Controller 將其動態寫入到負載均衡器配置中,從而實現整體的服務發現和負載均衡
有點懵逼,那就看圖
?
從上圖中可以很清晰的看到,實際上請求進來還是被負載均衡器攔截,比如 nginx,然后 Ingress Controller 通過跟 Ingress 交互得知某個域名對應哪個 service,再通過跟 kubernetes API 交互得知 service 地址等信息;綜合以后生成配置文件實時寫入負載均衡器,然后負載均衡器 reload 該規則便可實現服務發現,即動態映射
了解了以上內容以后,這也就很好的說明了我為什么喜歡把負載均衡器部署為 Daemon Set;因為無論如何請求首先是被負載均衡器攔截的,所以在每個 node 上都部署一下,同時 hostport 方式監聽 80 端口;那么就解決了其他方式部署不確定 負載均衡器在哪的問題,同時訪問每個 node 的 80 都能正確解析請求;如果前端再 放個 nginx 就又實現了一層負載均衡
?
1.4、總結
Ingress其實就是從 kuberenets 集群外部訪問集群的一個入口,將外部的請求轉發到集群內不同的 Service 上,其實就相當于 nginx、haproxy 等負載均衡代理服務器,有的同學可能覺得我們直接使用 nginx 就實現了,但是只使用 nginx 這種方式有很大缺陷,每次有新服務加入的時候怎么改 Nginx 配置?不可能讓我們去手動更改或者滾動更新前端的 Nginx Pod 吧?那我們再加上一個服務發現的工具比如 consul 如何?貌似是可以,對吧?而且在之前單獨使用 docker 的時候,這種方式已經使用得很普遍了,Ingress 實際上就是這樣實現的,只是服務發現的功能自己實現了,不需要使用第三方的服務了,然后再加上一個域名規則定義,路由信息的刷新需要一個靠 Ingress controller 來提供。
Ingress controller 可以理解為一個監聽器,通過不斷地與 kube-apiserver 打交道,實時的感知后端 service、pod 的變化,當得到這些變化信息后,Ingress controller 再結合 Ingress 的配置,更新反向代理負載均衡器,達到服務發現的作用。其實這點和服務發現工具 consul consul-template 非常類似。
現在可以供大家使用的 Ingress controller 有很多,比如?traefik、nginx-controller、Kubernetes Ingress Controller for Kong、HAProxy Ingress controller,當然你也可以自己實現一個 Ingress Controller,現在普遍用得較多的是 traefik 和 nginx-controller,traefik 的性能較 nginx-controller 差,但是配置使用要簡單許多,我們這里會以更簡單的 traefik 為例給大家介紹 ingress 的使用。
二、Traefik 使用
由于微服務架構以及 Docker 技術和 kubernetes 編排工具最近幾年才開始逐漸流行,所以一開始的反向代理服務器比如 nginx、apache 并未提供其支持,畢竟他們也不是先知;所以才會出現 Ingress Controller 這種東西來做 kubernetes 和前端負載均衡器如 nginx 之間做銜接;即 Ingress Controller 的存在就是為了能跟 kubernetes 交互,又能寫 nginx 配置,還能 reload 它,這是一種折中方案;而最近開始出現的 traefik 天生就是提供了對 kubernetes 的支持,也就是說 traefik 本身就能跟 kubernetes API 交互,感知后端變化,因此可以得知: 在使用 traefik 時,Ingress Controller 已經無卵用了,所以整體架構如下
?
2.1、部署 Traefik
首先通過Git下載Traefik源碼:
git clone https://github.com/containous/traefik.git下載完成后進入到 traefik\examples\k8s 文件夾,里面有我們需要用到的所有的配置文件:
traefik/examples/k8s這個目錄下就是traefik啟動需要用到的yaml文件。實際一般只需要使用traefik-deployment.yaml? traefik-rbac.yaml
traefik-rbac.yaml用于創建ServiceAccount traefik-ingress-controller,并創建相關的ClusterRole,? ClusterRoleBinding以對其進行授權。由于在Kubernets1.6之后啟用了RBAC鑒權機制,所以需配置ClusterRole以及ClusterRoleBinding來對api-server的進行相應權限的鑒權。那rbac這個文件呢就是創建ClusterRole和ClusterRoleBinding的,至于deployment文件這里就不說了,相信看到本篇文章的童鞋已經對K8S有了基本認識。
?
開始創建rbac
[root@k8smaster k8s]# kubectl apply -f traefik-rbac.yaml clusterrole.rbac.authorization.k8s.io "traefik-ingress-controller" created clusterrolebinding.rbac.authorization.k8s.io "traefik-ingress-controller" created檢查是否成功[root@k8smaster k8s]# kubectl get clusterrolebinding NAME AGE cluster-admin 113d flannel 113d heapster 113d kubeadm:kubelet-bootstrap 113d ………. traefik-ingress-controller 3s[root@k8smaster k8s]# kubectl get clusterrole NAME AGE admin 113d cluster-admin 113d edit 113d flannel 113d可以看到clusterrole,clusterrolebinding都創建成功了,下面創建Traefik。
[root@k8smaster k8s]# kubectl apply -f traefik-deployment.yaml serviceaccount "traefik-ingress-controller" created deployment.extensions "traefik-ingress-controller" created service "traefik-ingress-service" created檢查是否成功 [root@k8smaster k8s]# kubectl get svc,deployment,pod -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE heapster ClusterIP 10.106.236.144 <none> 80/TCP 113d kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 113d kubernetes-dashboard-external NodePort 10.108.106.113 <none> 9090:30090/TCP 113d traefik-ingress-service NodePort 10.98.76.58 <none> 80:30883/TCP ,8080:30731/TCP 17sNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE heapster 1 1 1 1 113d kube-dns 1 1 1 1 113d kubernetes-dashboard 1 1 1 1 113d traefik-ingress-controller 1 1 1 0 18sNAME READY STATUS RESTARTS AGE etcd-k8smaster 1/1 Running 6 113d heapster-6595c54cb9-f7gvz 1/1 Running 4 113d kube-apiserver-k8smaster 1/1 Running 6 113d ………. traefik-ingress-controller-bf6486db6-jzd8w 1/1 Running 0 17s可以看到service和pod都起來了。
剛才前面也說到了有個非常簡潔漂亮的界面,非常適合運維統計管理,下面來看看。
[root@k8smaster k8s]# kubectl apply -f ui.yaml service "traefik-web-ui" created ingress.extensions "traefik-web-ui" created運行完成后我們可以通過以下命令查看svc和pod運行情況:
kubectl get svc,deployment,pod -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 98d service/kubernetes-dashboard ClusterIP 10.107.232.92 <none> 443/TCP 98d service/traefik-ingress-service NodePort 10.105.165.76 <none> 80:31172/TCP,8080:32419/TCP 49m service/traefik-web-ui ClusterIP 10.96.161.200 <none> 80/TCP 47mNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.extensions/kube-dns 1 1 1 1 98d deployment.extensions/kubernetes-dashboard 1 1 1 1 98d deployment.extensions/traefik-ingress-controller 1 1 1 1 49mNAME READY STATUS RESTARTS AGE pod/etcd-docker-for-desktop 1/1 Running 27 98d pod/kube-apiserver-docker-for-desktop 1/1 Running 27 98d pod/kube-controller-manager-docker-for-desktop 1/1 Running 27 98d pod/kube-dns-86f4d74b45-cqwlk 3/3 Running 81 98d pod/kube-proxy-84jnm 1/1 Running 27 98d pod/kube-scheduler-docker-for-desktop 1/1 Running 27 98d pod/kubernetes-dashboard-7b9c7bc8c9-mzn8l 1/1 Running 49 98d pod/traefik-ingress-controller-7dcd6f447-fzzcw 1/1 Running 0 49mservice,pod都起來了,我們需要關注的一個svc是 service/traefik-ingress-service ,關注下它的接口:
80端口對應的服務端口,8080端口對應的是ui端口,也就是說我們可以通過訪問8080端口來訪問traefik的web界面,通過k8s集群的任意一個nodeIP:31695,都可以訪問到traefik的web ui界面
因為我是本地部署,所以瀏覽器直接瀏覽:http://127.0.0.1:32419 就可以:(如果是本地集群(非Docker安裝,VM虛擬機安裝),則需要用master的IP地址)
?
二、暴露服務
這里我們使用nginx服務測試,首先準備三個文件,分別是 nginx-deploy.yaml? ? ? nginx_ingress.yaml? ? ? ? nginx_service.yaml
[root@171 nginx]# cat nginx-deploy.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata:annotations:deployment.kubernetes.io/revision: "2"creationTimestamp: 2018-04-09T04:02:02Zgeneration: 4labels:app: nginxname: nginx-deploynamespace: defaultresourceVersion: "111504"selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployuid: c28090c0-3baa-11e8-b75a-000c29858eab spec:replicas: 2selector:matchLabels:app: nginxstrategy:rollingUpdate:maxSurge: 1maxUnavailable: 1type: RollingUpdatetemplate:metadata:creationTimestamp: nulllabels:app: nginxspec:containers:- image: nginx:1.9.1imagePullPolicy: IfNotPresentname: nginxports:- containerPort: 80protocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstrestartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30 status:availableReplicas: 2conditions:- lastTransitionTime: 2018-04-09T04:57:27ZlastUpdateTime: 2018-04-09T04:57:27Zmessage: Deployment has minimum availability.reason: MinimumReplicasAvailablestatus: "True"type: AvailableobservedGeneration: 4readyReplicas: 2replicas: 2updatedReplicas: 2 [root@171 nginx]# cat nginx_service.yaml apiVersion: v1 kind: Service metadata:creationTimestamp: 2018-04-09T11:34:09Zlabels:run: nginxname: nginxnamespace: defaultresourceVersion: "140236"selfLink: /api/v1/namespaces/default/services/nginxuid: eb57a21b-3be9-11e8-b75a-000c29858eab spec:clusterIP: 10.99.59.56ports:- port: 80protocol: TCPtargetPort: 80selector:app: nginxsessionAffinity: Nonetype: ClusterIP status:loadBalancer: {} [root@171 nginx]# cat nginx_ingress.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata:creationTimestamp: 2018-04-09T11:39:48Zgeneration: 1name: testnamespace: defaultresourceVersion: "140644"selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/testuid: b54bbda8-3bea-11e8-b75a-000c29858eab spec:rules:- host: test.nginx.comhttp:paths:- backend:serviceName: nginxservicePort: 80 status:loadBalancer: {}然會加載三個配置分件,分別生成deployment、ingress和服務Service:
kubectl create -f nginx-deploy.yaml --record kubectl create -f nginx-service.yaml --record kubectl create -f nginx-ingress.yaml --record查看pod:
kubectl get pods -o wide | grep nginx關注下pod的IP地址,這個時候我們已經可以在本地的集群內訪問nginx了,運行以下命令測試:
curl http://10.244.1.19然后查看下ingress和Service的狀態:
kubectl get ing | grep nginx kubectl get svc | grep nginx我這里用的VM虛擬機,NAT網絡模式,暫時只能在集群內部訪問,想要通過本機和外網訪問還需要配置下,將pod的ip段轉發到本機master或者node的IP:
這里以master的IP地址為列,首先你需要查看下你虛擬機master的IP地址,我這里是192.168.3.131
然后通過route print查看自己電腦上vmnet8網卡對應的網卡接口編號:
我這里是15,我們需要將k8s的服務Service和pod網段的請求轉發到我們的master虛擬機:
route add 10.99.0.0 MASK 255.255.0.0 192.168.3.131 IF 15 route add 10.244.0.0 MASK 255.255.0.0 192.168.3.131 IF 15成功之后我們就可以通過pod和Service的IP地址在瀏覽器里訪問了:
?
查看下Traefik的UI會看到對應的ingress已經顯示了出啦:
可以看到Traefik的UI上多了一個名稱為test.nginx.com的選項卡,這個名稱是我們在Ingress.yaml中指定的hsot,我們是可以通過這個名稱來直接路由請求的,但是需要配置下windows的hosts文件:
打開路徑:C:\Windows\System32\drivers\etc ,找到hosts文件編輯:
?
我們剛才已經將nginx服務(Service)的訪問轉發到master虛擬機,所以我們需要配置下映射關系,test.nginx.com域名的請求轉發到Service的IP,然后就可以訪問了:
?
轉載于:https://www.cnblogs.com/weiBlog/p/10467971.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Kubernetes 系列(三):Kubernetes使用Traefik Ingress暴露服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU - 2612 Find a wa
- 下一篇: Shell命令-内置命令及其它之exec