Kubernetes 簡介

什麼是Docker

Docker不是虛擬機。 在不少的網絡教案中喜歡將Docker與虛擬機進行類比,這種類比用於理解Docker的優點有着不錯的做用,由於Docker與虛擬機有着相同的優點。可是從技術而言,虛擬機技術則是對硬件層的虛擬化,而Docker是一種進程隔離技術。簡單的說,咱們能夠在宿主機(Host Machine)使用 ps aux 看到使用Docker啓動的進程。這意味着Docker中的程序其實是跑在宿主操做系統中。這是我不同意將Docker與虛擬機進行類比的緣由。html

要去理解Docker,最避不開的是Namespace 與Cgroups。linux

Namespace 是Linux中對進程之間進行隔離保護的技術。經過Namespace技術,保證了不一樣Docker Container中看到的內容不同,這也是Docker的基礎。nginx

cgroups(Control Groups)最初叫Process Container,由Google工程師(Paul Menage和Rohit Seth)於2006年提出,後來由於Container有多重含義容易引發誤解,就在2007年改名爲Control Groups,並被整合進Linux內核。顧名思義就是把進程放到一個組裏面統一加以控制 。本質上,Cgroups 是一種對進程資源控制(好比可訪問內存,CPU時間使用)的技術手段。 sql

這裏咱們能夠更加清楚的明白,Docker只是一個基於操做系統提供的虛擬化能力的一個上層應用,其核心功能都是由內核實現。這也是與虛擬機最大的不一樣點。docker

什麼是Kubernetes

Kubernetes 是一個由Google 主導開發的開源容器編排平臺,經過數年的發展已經成爲了容器編排的事實標準。各大雲平臺也都提供了完善的Kubernetes功能,咱們能夠在Kubernetes的源碼中看到目前適配的雲平臺。數據庫

在Kubernetes的世界裏,咱們不在關心具體的服務器細節,咱們看到的是一個一個CPU,一條一條內存,一塊一塊的磁盤擺在眼前,服務器已經被徹底的抽象爲計算資源。應用服務器的無狀態化帶來的最大好處是擴容的便利性,咱們能夠藉助雲平臺,在數分鐘內完成百倍的吞吐量擴展。另外一方面,對於應用開發者,全部的一切都在kubectl 這一個工具中。後端

Kubernetes 基礎服務

0. Master

Master 管理着整個集羣的狀態與訪問。api

1. 節點

節點(Node)表明着一臺物理實例。全部集羣中的容器都運行在節點中。一旦某一個節點發生故障,則運行在該節點的容器會自動的遷移到其餘節點(注意,遷移的過程是銷燬重建。事實上爲了狀態的一致性,在Kubernetes中沒有容器的中止與重啓的概念)。服務器

在集羣運行中,咱們能夠添加/減小節點。在節點新增以後,網絡

2. 網絡

在集羣(Cluster)內部,Kubernetes使用虛擬網絡層進行網絡通信。這使得每個容器都有一個本身獨立的ip。咱們能夠從任何一個容器經過這個ip訪問到另外一個容器內部。

對於Web應用,咱們常常須要部署多個實例用於負載均衡,在Kubernetes,能夠經過Service服務很是快速的建立一個內部負載均衡(ELB)。對於每個Service,仍然會分配一個ip,使得咱們能夠從一個容器去訪問另一組容器而無需任何額外的程序(例如Haproxy,Nginx)支持。

在虛擬網絡之上,Kubernetes還提供了針對虛擬網絡的DNS系統,咱們只須要按照特定的規則就能夠訪問不一樣的Service,連ip都不須要知曉。

虛擬網絡徹底的避開了對於物理網絡細節(例如Ip 地址,端口號)的依賴,使得咱們能夠經過配置獲得一個徹底一致的集羣環境。

除了使用虛擬IP進行訪問以外,Kubernetes還提供了基於DNS的訪問辦法。

3. 存儲

咱們永遠不該該在容器中存儲任何須要持久化存儲的數據(Mysql,Redis),由於容器會崩潰重建,故障遷移等緣由形成自動從新部署,這些動做都會形成數據的丟失。若是在容器中須要使用持久化存儲,咱們須要使用 Persistent Volume 服務。該服務經過將外部的持久化存儲系統掛載到容器中進行使用。對於一塊磁盤,能夠掛載一個容許寫操做的捲到一個容器,以及掛載多個只讀權限給多個容器。

4. 配置

不建議將容器中應用程序的配置文件在構建鏡像(Docker Image)的時候打包進去,這會形成配置文件的變動須要從新構建。在Kubernetes中,提供了ConfigMap服務進行配置文件的管理。

咱們經過會經過ConfigMap來構建應用程序的配置管理,而後將其掛載到容器中使用。這能夠很是容器的讓咱們的應用程序跑在不一樣的環境中。

5. 調度

當咱們向集羣新增長一個(些)容器的時候,集羣會自動將容器部署到合適的節點。集羣會根據不一樣節點(Node)的狀態(節點狀態,節點資源狀態)來進行規劃,而且自動部署。在新增容器的時候,咱們還能夠指定對應的Node Label將不一樣的服務部署到不一樣的物理實例中,以實現服務的物理隔離。

Kubernetes 核心概念

1. Pod

Pod 是一個或多個Docker容器的組合,它們之間具備共享的存儲與網絡。Pod也是Kubernetes的最小單位,Pod中的容器會保證永遠運行於同一個節點。

好比對於PHP-FPM應用而言,須要PHP-FPM進程與對應的Web Server(Nginx,Apache)。基於Docker最小部署原則,咱們會將PHP-FPM與Web Server分爲兩個鏡像。咱們能夠在一個Pod中同時部署PHP-FPM鏡像與Web Server進程,而且它們之間仍然能夠經過fastcgi的方式進行通信。而Kubernetes又保證了這些容器具有相同的生命週期。咱們將總體理解爲一個應用程序便可。

2. Development

部署(Development)是一個針對如何管理Pod的工具。經過Development咱們能夠快速地建立多個Pod副本,而且支持滾動熱更新,從而實現了應用程序的熱更新。咱們能夠簡單的將部署理解爲應用的多服務器管理技術手段,在物理機時代,有ansible這樣的工具來進行批量部署。

3. Service

咱們已經使用部署將咱們的應用部署在了多臺節點中,儘管Kubernetes已經提供了虛擬IP來讓咱們進行不一樣容器之間的通信,可是這個IP是不穩定的,由於咱們的節點會進行故障遷移,宕機,從而可能更新IP。那麼咱們如何訪問這些服務? 答案就是Service。

Service將一些Pod關聯在一塊兒,而且設定一些訪問策略(好比端口映射),而且容許設定一個固定的ip。當咱們嘗試去訪問這些服務的時候,咱們只須要訪問Service的ip與端口(映射以後的Service端口)就能夠訪問這些服務,而且Service自己能夠進行負載均衡與健康檢查。

這意味着Service是一個內部負載均衡器(ELB)。

4. Ingress

Ingress本質上和Service同樣,也是一種流量代理的概念,可是與Service不同的是:

a. Service是4層代理,Ingress是7層代理(Http)。
b. Service是服務的集羣內部訪問方法,Ingress則是經過一組規則來控制從外部系統(internet)到多個服務的訪問方法。

咱們能夠設定不一樣的域名,不一樣的Http url path 路由到不一樣的後端服務(Backend Service)。 所以,Ingress表明着流量入口和負載均衡(LB)的做用。

5. StatefulSet

從概念上,StatefulSet與Development是很是的類似,可是不一樣點是:Development是對無狀態Pod的管理(好比Http Server),而StatefulSet則是對有狀態的Pod進行管理,好比(數據庫 MySQL),同時會遵循固定的順序進行啓動或銷燬容器。

一般地,StatefulSet服務都會搭配持久化存儲服務一塊兒工做,咱們會將數據庫的數據目錄指向持久化存儲中,這保證了容器在銷燬、重建以後數據仍然不會丟失。

6. DaemonSet

Daemon Set是一種獨特的部署方式,它保證了容器會運行在全部指定的節點中,而且保證在節點生命週期內一直存活。這一般適用於一些節點監控程序或採集程序。好比fluentdlogstash

7. Job

Job是一種一次性工做程序的部署方式。它會在全部指定的Pod運行完以後結束生命週期。好比咱們可使用Job來運行數據庫遷移程序。

8. CronJob

從名稱可知,CronJob是計劃任務的方式來運行程序,而且使用Cron語法來描述間隔週期,可是CronJob會有一些須要注意的地方:

a. CronJob是分佈式的,它不會保證運行在某一個肯定的節點中,除非在YAML中指定。
b. CronJob可能由於調度的問題,形成運行屢次,這須要咱們保證CronJob程序的冪等性。

Kubernetes YAML 格式分析

Development YAML Sample

apiVersion: apps/v1 #當前服務的API版本,對於Beta中的服務,須要在部署Kubenetes集羣中進行開啓容許使用beta服務。
kind: Deployment #不一樣的服務類型使用Kind進行標記,好比Service,Ingress
metadata:
  name: nginx-deployment  #name是一個很是有用的屬性,它會在DNS系統中會使用
  labels:
    app: nginx  #當前服務的標籤設定
spec:
  replicas: 3  #Pod的副本數量
  selector:
    matchLabels:
      app: nginx
  template:  #Pod的模板
    metadata:
      labels:
        app: nginx 
    spec:
      imagePullSecrets:    #若是鏡像使用的私有鏡像倉庫,則須要指定docker倉庫的key才能夠pull docker鏡像
      - name: DOCKER_PULL_KEY_NAME
      containers:
      - name: nginx    #容器名稱
        env:     #附加到容器中的環境變了
        - name: ENV_NAME
          value: ENV_VALUE
        image: nginx:1.7.9 #鏡像
        ports:
        - containerPort: 80 #容器內部的須要導出的端口

總結

Kubernetes 憑藉着Google多年的大規模服務器管理經驗,將後端架構完整的抽象出了一些更高級別的概念,在這些概念中咱們徹底脫離了服務器自己的限制,不在操心具體的服務器配置。咱們能夠將更多的精力關注本身的應用。

參考資料

  1. http://man7.org/linux/man-pag...
  2. https://www.kernel.org/doc/Do...
相關文章
相關標籤/搜索