以下内容根據演講嘉賓現場視訊以及速記整理而成。
原文連結今天主要會分享三個方面的問題:
Kubernetes的基本概念介紹
如何在阿裡雲快速一鍵部署高可用安全的Kubernetes叢集
Kubernetes在阿裡巴巴的Cloud Provider,也就是雲廠商的內建提供的一些能力
首先簡單介紹一下Kubernetes。Kubernetes簡稱K8S,這是社群的一種叫法。Kubernetes是整個CaaS工作流中的一環,CaaS是什麼呢?就是Container As A Service——容器即服務,下圖中的右圖是一個簡化版的CaaS的架構圖,從最底層是一個基礎服務,其上層主要提供的是實體機、網絡、存儲等一些比較硬體化的基礎設施。再往上一層會建構PaaS平台,PaaS平台裡頭主要傳遞的對象是一些虛拟機,或者邏輯的結構,比如邏輯的VPC網絡、存儲等,讓你可以友善地一鍵去建立這些資源,而不需要再去機房裡頭自己去運維管理這些東西。然後在PaaS平台上面會建構一層容器平台,這一層中主要的互動單元就是容器。
對于容器服務來講,在這一層的時候,就更不需要關心于底層的PaaS平台所具有的特性了,比如在建立應用的時候,不需要關心底層使用的虛拟機是什麼,或者是否需要手動建立一個虛拟機網絡以及存儲,然後去建構并放置應用去運作,這個時候隻需要首先聲明應用,然後告訴它說我需要在這個CaaS平台裡運作我的應用,然後其他的事情你就不用操心了。平台會主動地幫你去尋找最合适的機器以及最合适的環境,把應用布置上去,并幫你解決好應用的故障恢複,網絡的通路情況,以及資源配置設定問題。Kubernetes的這個層次之上是上圖綠色部分,它屬于編排系統,可以很友善地把應用按照系統合适的方式分布到各個節點上去,然後由它來處理故障恢複、副本保證等資源排程問題。另外它還提供容器的生命周期管理,比如啟停一個應用、當應用失敗之後重新拉起,或者不需要這個應用後執行删除等操作。
接下來分享一下Kubernetes的一些基本的概念,一個比較核心的概念就是Pod,Pod是一組容器的統稱,就是它把一組容器作為一個最基礎的排程單元,這組容器會被協同排程到一起,比如說有兩個屬于同一個Pod的容器,那麼它們會被排程到同一個節點,一起排程,一起Fail Over。Service是一組Pod的抽象,比如在建立應用的時候可能需要建立很多個Pod來同時對外界提供服務,那麼這一組Pod是同一個層次的東西,具有同等的地位,在前面提供一個Services對這一組Pod做負載均衡,當通路這個Services的時候,就會從後端随意挑出一個Pod來為前端提供服務,相當于負載均衡的概念,不過Services是叢集内部的,它的網絡隻會局限于叢集内部。
另外一個是Deployment概念,這是一個描述性的概念,就是當描述一個應用的時候就需要聲明這個應用需要達到的狀态,比如需要它有三個副本一直運作,需要它在故障的時候能夠自動拉起來。用Deployment來描述它,然後系統就會自動保證這些東西,一旦出現了不符合預期的情況,系統會自動把這個狀态轉化到正常,無論是通過重新建立一組Pod或者是拉起原來的Pod。在K8S裡面還有一個另外比較重要的概念就是持久化卷,通常來講容器在建立的時候是沒有資料卷的,對于存儲在容器中的資料,如果把容器删掉了,那麼這個資料也就會丢失。K8S提供一個持久化卷的概念,就是在建立服務的時候,可以先建立出這個卷,然後把這個卷挂載到容器裡頭去。通過這樣的方式,在删除容器時,持久化卷是不會被删除的,資料也就可以保留下來。
下圖是K8S的架構示意圖,這是一個典型的無狀态、多Master的分布式架構圖。K8S主要功能元件:Kubelet,相當于Agent,在每一個節點上提供一個守護程序的服務,上報節點狀态、運作Controller等。aplserver是一個Master,它是無狀态的,所有的資料都存在後端的一緻性存儲中。Scheduler負責排程所有的Pod,也就是應用,為應用找一個合适的位置并運作起來。
這裡前端使用一個Load Balancer來提供一個高可用的負載均衡的服務,其中一個Master挂了之後,仍然會有其他的幾個Master會提供服務,是以不用擔心會有幾個Master 挂掉了。
在使用K8S當中遇到的一個比較大的問題就是部署問題。衆所周知K8S一直在業界被诟病的就是太難用了,元件太多,概念太多,導緻無法了解。對于開發者來講,不希望去操心如何把叢集快速地部署起來,如何去了解底層的東西,隻需在用到的時候能夠部署一個叢集出來,這是需要達到最終的目标,就是部署簡單。

看一下現在比較流行的一些部署工具,Kubeup是最早期的一種部署工具,它支援多種的環境,CentOS、Ubuntu,J2EE以及AWS等等,但是目前沒有辦法直接在阿裡雲上面部署起來,需要一些手工的改動。Kargo的底層主要使用的是Ansible,适合對Ansible比較熟悉的人去部署使用。Kops與AWS等雲廠商內建度比較高,是以在AWS下面比較好用。Kubeadm主要是K8S原生支援的,也是未來官方主推的一種方式,它的特點就是簡單易用,但是目前還處在α階段,還不支援HA。但是這并不妨礙我們去使用它部署出一個HA的K8S叢集。
那麼阿裡雲的選擇是什麼呢?ROS + Kubeadm,原因隻有一個:簡單。首先簡單介紹一下ROS,ROS是阿裡雲的資源編排服務,它可以非常友善的在阿裡雲一鍵建立出來所需要的各種資源比如ECS、VPC網絡、SLB以及其他資源等等,相關的文檔大家可以去阿裡雲官網檢視。
一鍵部署主要分為三個步驟:
進入到ROS的控制台,這裡有一個Kubernetes for chinese版本的,然後去點選建立。
選一個建立的區域。
填寫建立的叢集名稱,填寫節點的密碼,點選建立。
這就是一鍵建立,非常簡單。
主要的部署過程分為三個步驟:第一個是建立叢集需要提供阿裡雲的KeyID跟KeySecret,首先需要設定這兩個環境變量,然後需要從阿裡雲官方網站上下載下傳一個腳本,執行一個node-type=Master指令,這個指令要在Master上執行,這樣執行完了之後就在這台機器上初始化了一個Master了,然後它會傳回一個Token和節點的IP。第二步再到node節點上面去把node-type改為node,然後帶上KeyID跟KeySecre以及剛才傳回的End Point和Token,就可以把這個結點加入到剛才建立的Master叢集當中,如此反複,就可以把更多的節點加入到叢集中去。當不想要某個節點的時候,還可以通過node-type = down的指令銷毀掉這個節點。
注意的地方就是在建立叢集的過程中一定要保證hostname的一緻性,CP的規範是使用hostname作為校驗ECS一緻性的參數,是以一定要保證hostname與傳給CP的值是一樣的。另外一個是阿裡雲的安全組設定問題,安全組預設禁止了所有非VPC位址的通路,是以需要根據最小需求設定來開放安全組,CP使用了172.16以及172.19網段,需要把這兩個網段開放出來,同時還需要開放30000到32768的主機端口,用來給Service提供服務。第三個比較重要的是CentOS預設的核心配置的問題,這個要求配置核心的net.bridge.bridge-nf-call-iptables=1參數,否則所有主機上網橋的資料流量都不會經過iptables規則的轉化,進而導緻服務沒有辦法互相通路。如果這些還沒有辦法解決問題,那可以祭出終極大殺器——tcpdump,然後抓包分析資料。
接下來介紹一下K8S的阿裡巴巴Cloud Provider,阿裡雲的Cloud Provider支援如下的一些特性:比如在網絡支援方面,支援VPC的網絡、阿裡雲的SLB以及Ingress network;存儲方面,支援NAS、OSS。支援跨Region的單叢集部署方案,可以把叢集部署在多個可用區,甚至多個Region上,這樣當出現單可用區fail的時候,叢集仍然是可用的,提供了一種高可用的方案。還可以在K8S上使用原生的ELK作為日志方案,也可以使用阿裡雲提供的Fluentd-pilot開源解決方案,這個可以和阿裡雲的日志服務提供完整的對接,也是非常不錯的選擇;然後監控方面也可以通過阿裡雲監控來監控node節點的狀态,也可以選擇使用原生的Heapster + inluxdb來做網絡監控方案;在應用倉庫方面,可以使用現在開源的Helm/tiller的方式。
然後我們來看一下我們的VPC網絡支援,Kubernetes支援非常豐富的網絡形态,如VXLAN、Calico以及VPC網絡等,VXLAN主要是一種Overlay,它通過對IP層然資料進行二次封裝,封裝完了之後在通過主控端的網絡路由到對端主機之後,然後再進行解封裝,解封裝之後再放到主機的核心棧裡頭,處理這些協定然後解碼出來,傳到另外Container容器裡的網絡裡頭,這個過程涉及到了一個資料包的封裝與解封裝,是以它的性能會有稍微的損耗。
Calico網絡是通過3層路由的方式實作的,它直接把網關指向了對端節點的主機IP,這樣所有發送到對端節點上面的容器IP的資料包都可以直接先發到對端節點上,然後由對端節點直接路由給容器。這種方式的好處是沒有資料包的額外封裝,是以性能損耗非常小。但是它要求所有的主機之間是二層可達的,這個要求通常對于許多雲廠商來說是無法滿足的,但是自建機房一般是都可以用的。然後就是VPC網絡,阿裡雲VPC的方案跟Calico非常類似,也是通過路由的方式,然後把一個節點的容器的資料包導到另一個節點上的容器中去,是以性能損耗非常小,推薦大家使用VPC網絡,而且現在阿裡雲支援的K8S也是僅僅支援這一種網絡。當然你也可以使用VXLAN網絡,但是VPC網絡會提供給你的更好的性能,而且它還提供租戶隔離級别的網絡環境,網段也可以自由劃分,而且如果把多個交換機建立在不同的可用區之内,還可以提供一種可用區級别的Fail Over。
實踐過程中比較多的問題都來自于客戶想了解VPC網絡的性能究竟如何。在這裡通過幾種不同的方案來測試了一下VPC性能,主要有netprof、iprof以及qprof,下圖是得出來的結果。從這些結果來看,容器的VPC網絡跟主機VPC網絡差距是非常小的,性能損耗是幾乎是沒有的,當然不同的人在不同的環境下測出來的結果會有略微的差異,大家可以自己測試一下。
阿裡雲的CP還支援自己的LSB,前面提到的Service的通路範圍隻是在叢集内部,如果想要從叢集外部來通路叢集内部所提供的服務,那就需要一個入口點。阿裡雲Load Balancer可以支援這樣的功能,這個功能也內建到了阿裡雲的Cloud Provider中,使用的時候隻需要在建立應用的yaml File中指定service 的type = Load Balancer,然後就可以建立一個阿裡雲Load Balancer,然後它會自動地把Load Balancer關聯到後端應用伺服器,然後提供給使用者一個靜态的IP外網接入口,這樣就可以通過IP來通路到叢集内部的服務了,并且還提供了HTTPS的支援,使用者可以上傳自己的證書來提供HTTPS服務,還可以自定義SLB的帶寬、健康檢查類型以及URL、收費類型等。
K8S的Service是叢集範圍内的,同時阿裡雲現在提供另一套解決方案就是使用Ingress。Ingress可以把外部的流量引入進來,那麼這與上面提到的LSB有什麼差別呢?其實LSB是一個四層的東西,在IP層做負載均衡,而Ingress支援七層的負載均衡,它可以提供一種簡單的路由服務,比如把某個域名的url定向一個Service的後端,也可以提供一種簡單的服務的Fanout,就是可以用一個域名來提供服務,并根據不同的URL來定位到後端不同服務上去。使用者也可以使用多個域名來提供服務,這類似于虛拟主機路由的方式,不同的域名會被路由到不同的後端服務上去。
然後右邊這個是一個簡單的架構圖,最上層是阿裡雲的SLB,阿裡雲的SLB它的流量會被定位到兩個Ingress Controller Pod裡頭去,這兩個是一個簡單的Nginx實作,通過這個Nginx做7層負載均衡,然後把這些流量再定位到你的應用Pod裡面。另外一個特點它支援豐富的Annotation,可以支援SSL,第三方授權,ORL的Rewrite白名單管理等等這些功能。
阿裡雲的Cloud Provider還支援各種存儲,比如NAS存儲、OSS存儲等。NAS存儲是由原生的K8S的NFS驅動支援的。在這裡簡單介紹一下KBS的Volume的使用機制,K8S的PV就是一個持久化的卷,這需要由叢集管理者首先在叢集中建立出來作為一個叢集内的資源,如果應用方想要在應用中使用,要先建立一個PVC,并要宣稱要使用叢集的存儲資源,然後K8S會從所有的叢集Volume裡面去挑選出最合适、最比對的,把它們綁定起來,綁定就意味着你可以使用這個PVC了。對于應用來講,需要在Pod裡面去聲明需要使用PVC,然後應用就和PVC綁定起來了,這樣在建立應用的時候,K8S就會把這個挂載到應用Pod裡去,這樣就可以像寫本地磁盤一樣去寫Persistent-Volume。
阿裡雲還支援多可用區,主要是為了實作可用區的Fail Over。讓使用者可以在多個可用區之中建立叢集,即使其他可用區Fail了,服務仍然是可用的。
阿裡雲還提供跨Region的支援。可用區級别是在各個可用區之間的,而同一個Region下的各個可用區的網絡是連通的,是以部署起來非常簡單。但是各個Region之間的網絡是不通的,需要通過阿裡雲的高速通道把各個Region的網絡首先打通,然後再部署應用。那麼這裡有一些限制,就是預設情況下,跨Region的阿裡雲資源是無法通用的,就是說在Region裡面隻能使用這個Region的資源,是以通常建議在每一個Region裡面建立相同的資源,比如說SLB,建立一個應用之後,把這些應用的Pod平鋪排程到多個Region當中,然後在每個Region中建立出一個SLB,把它綁定到應用上去。這樣的好處是什麼呢?綁定到SLB,然後在最外端提供一個智能DNS解析,把流量分别導入到這兩個Region中,這樣做可以支援一種鄰近使用者路由,比如說在杭州有一個Region,一些使用者也在杭州,那麼就會把杭州的使用者導到杭州的Pod節點上面去,這樣它的使用者響應速度是非常快的,然後歐洲的使用者就可以全部導到歐洲的叢集裡面去,是以這個對鄰近使用者選擇是非常有幫助的。下圖展現的就是跨Region支援的細節圖。