天天看點

如何在Kubernetes中暴露服務通路

Kubernetes概述

最近的一年,kubernetes的發展如此閃耀,正被越來越多的公司采納用于生産環境的實踐。同時,我們可以在最著名的開發者問答社群StackOverflow上看到k8s的問題數量的增長曲線(2015.5-2016.5),開發者是用腳投票的,從這一點看也無疑證明了k8s的火爆程度。

<a href="http://s2.51cto.com/wyfs02/M01/8D/57/wKioL1iZJWqinXw6AAA2Z_mnq1Q071.jpg" target="_blank"></a>

k8s來源于Google生産環境的實踐,社群活躍度很高,在github上的Star數17k+,30k+commits,同時由Google主導CNCF基金會也在強力運作k8s的社群發展,也就在幾個月前OpenStack社群宣布全面擁抱k8s,這也宣布了全球第大的開源IAAS雲社群已經選擇k8s作為容器的唯一解決方案。

<a href="http://s3.51cto.com/wyfs02/M00/8D/57/wKioL1iZJZWTwMHTAABERnhi9hA288.jpg" target="_blank"></a>

談到k8s,無論怎樣的議題怎樣的開始,我們都先介紹一個k8s整體架構(如下圖所示):

<a href="http://s1.51cto.com/wyfs02/M01/8D/57/wKioL1iZJbSj5AdOAABrI1PAaJQ543.jpg" target="_blank"></a>

etcd 作為配置中心和存儲服務,儲存了所有元件的定義以及狀态,k8s的多個元件之間的互互相動也主要通過etcd;kube-apiserver 提供和外部互動的接口,提供安全機制,大多數接口都是直接讀寫etcd中的資料;kube-scheduler 排程器,主要幹一件事情,監聽etcd中的pod目錄變更,然後通過排程算法配置設定node,最後調用apiserver的bind接口将配置設定的node和pod進行關聯;kube-controller-manager 承擔了master的主要功能,比如和CloudProvider(IaaS)互動,管理node,pod,replication,service,namespace等。基本機制是監聽etcd /registry/events下對應的事件,進行處理;kubelet 主要包含容器管理,鏡像管理,Volume管理等;kube-proxy 主要用于實作k8s的service機制。提供一部分SDN功能以及叢集内部的智能LoadBalancer。

本文分享的内容主要是在minion節點上的pod和service上,pod是k8s應用的具體執行個體抽象,而service便是這些抽象的集合。

<a href="http://s3.51cto.com/wyfs02/M02/8D/5A/wKiom1iZJdei7fjDAACNx5QdG2U158.jpg" target="_blank"></a>

ClusterIP &amp; NodePort &amp; Loadbalancer

回到本文的主題,在k8s中暴露Service通路(無論内部還是外部),都要經過kube-proxy,比如下圖中我們定義一個Service,便可以通過通路Service的80端口轉發到Pod的9376端口上。

<a href="http://s3.51cto.com/wyfs02/M02/8D/57/wKioL1iZJfvDe4UeAAB4407x804964.jpg" target="_blank"></a>

kube-proxy在轉發時主要有兩種模式Userspace和Iptables。如下圖,左側是Userspace模式,也是kube-proxy預設的方式,所有的轉發都是通過kube-proxy軟體實作的;右側是Iptables模式,所有轉發都是通過Iptables核心子產品實作,而kube-proxy隻負責生成相應的Iptables規則。從效率上看,Iptables會更高一些,但是需要Iptables version &gt;=1.4.11,Iptables模式在k8s1.2版本放出,是否開啟使用還需要具體斟酌。

<a href="http://s2.51cto.com/wyfs02/M02/8D/57/wKioL1iZJhWRyyqaAABTP5maabU521.jpg" target="_blank"></a>

從Service本身看,有三種方式來暴露通路:

ClusterIP:使用叢集内的私有ip —— 這是預設值

NodePort:除了使用cluster ip外,也将service的port映射到每個node的一個指定内部port上,映射的每個node的内部port都一樣。

LoadBalancer:使用一個ClusterIP &amp; NodePort,但是會向cloud provider申請映射到service本身的負載均衡。

LoadBalancer Provider主要有aws、azure、openstack、gce等雲平台提供。相關實作可以在k8s的源碼中看到,如下圖所示:

<a href="http://s4.51cto.com/wyfs02/M00/8D/5A/wKiom1iZJjTiUdsgAABTtSnjZL8284.jpg" target="_blank"></a>

Ingress

Ingress也是k8s中單獨定義的對象(如下圖所示),它的作用就是實作對外暴露通路的負載均衡,那麼它和Service本身LoadBalancer有哪些差別呢?Ingress支援L4、L7負載均衡,LoadBalancer設計上隻支援L4;Ingress基于Pod部署,并将Pod網絡設定成external network;Ingress controller支援Nginx、Haproxy、GCE-L7,能夠滿足企業内部使用。

<a href="http://s1.51cto.com/wyfs02/M00/8D/57/wKioL1iZJlLjz2MMAABCHRadbfU708.jpg" target="_blank"></a>

在實際使用時,Ingress的架構如下圖所示:

<a href="http://s3.51cto.com/wyfs02/M01/8D/57/wKioL1iZJm6CT0w3AABixCzr_hk297.jpg" target="_blank"></a>

但是在實際使用中,pod可能會産生漂移,由于Ingress Controller也是基于Pod部署,這樣Ingress對外的IP會發生變化。在企業内部都會在防火牆上給Service的通路IP設定規則,而IP變動對這一機制是緻命的,因為企業不可能經常手動修改防火牆規則。

那麼我們就需要一個VIP功能,同時也要能保證Ingress的HA。我們可以考慮在Ingress Controller基礎上增加一個keepalived,可以利用keepalived+haproxy的機制來完成VIP的功能。要實作這一機制,可以參考并改動k8s社群中的contrib-keepalived-vip機制。

<a href="http://s5.51cto.com/wyfs02/M00/8D/5A/wKiom1iZJobAPUsgAABx1A8m3oI801.jpg" target="_blank"></a>

除了以上介紹的暴露服務機制,還有Hpcloud-service-loadbalancer ,它實作了支援keepalived+nginx、F5、OpenStack Lbaas這些方式,并且支援L4 &amp; L7負載均衡,但是與k8s社群本身的發展機制并不相容,是以一直沒有被合并到社群中。另外還有 Contrib-service-loadbalancer ,這個是社群内部正在發展的,它的想法更遠大,考慮會支援Cross-namespace、 Cross-cluster這種級别的負載均衡,同時也是設計了插件機制,目前支援Haproxy,同樣也支援L4 &amp; L7負載均衡。

Rancher K8s中暴露服務通路

Rancher自己實作了一個rancher-ingress-controller,它本質上是包裝了k8s-ingress-controller,在真正建立負載均衡器上它會調用Rancher Cattle API來建立Rancher自身的LB。

<a href="http://s3.51cto.com/wyfs02/M00/8D/57/wKioL1iZJrqC_11BAABOJFWXYB8204.jpg" target="_blank"></a>

相關代碼也是開源的,https://github.com/rancher/lb-controller,lb-controller在啟動時候會指定provider為rancher,對應的實作也可在package provider/rancher中看到。

<a href="http://s4.51cto.com/wyfs02/M01/8D/5A/wKiom1iZJtLiONeBAACDxdnDPjE066.jpg" target="_blank"></a>

建立Ingress後,也可在Rancher UI上展現出來。

<a href="http://s3.51cto.com/wyfs02/M00/8D/5A/wKiom1iZJu7gacGKAABbGz5Ewac803.jpg" target="_blank"></a>

本文轉自 RancherLabs 51CTO部落格,原文連結:http://blog.51cto.com/12462495/1895492