天天看點

k8s實戰讀書筆記

  kubernetes中Service是真實應用的抽象,将用來代理Pod,對外提供固定IP作為通路入口,這樣通過通路Service便能通路到相應的Pod,而對通路者來說隻需知道Service的通路位址,而不需要感覺Pod的變化;

  Service是通過Label來關聯Pod的,在Service的定義中,設定 .spec.selector為name=redis-master,将關聯上Pod;

  #kubectl get service redis-master

  NAME   CLUSTER_IP  EXTERNAL_IP   PORT(S) SELECTOR    AGE

  redis-master 10.254.233.212 <none>     6379/TCP         13s

  Redis Master Service 的查詢資訊中的顯示屬性CLUSTER_IP為10.254.233.212, 屬性PORT(S)為6379/TCP, 其中10.254.233.212是Kubernetes配置設定給Redis Master Service的屬性IP,6379/TCP則是Service會轉發的端口(通過Service定義檔案中的.spec.ports[0].port指定),Kubernetes會将所有通路10.254.233.212:6379的TCP請求轉發到Redis Master Pod中,目标端口是6379/TCP(通過Service定義檔案中的spec.ports[0].targetPort指定)。

  因為建立了Redis Master Service來代理Redis Master Pod,是以Redis Slave Pod通過Redis Master Service的虛拟IP 10.254.233.212就可以通路到Redis Master Pod,但是如果隻是硬配置Service的虛拟IP到Redis Slave Pod中,這樣還不是真正的服務發現,Kubernetes提供了兩種發現Service的方法;

  note: 如何在外部網絡中通路Redis Master Service呢?

    因為Service的虛拟IP是由k8s虛拟出來的内部網絡,而外部網絡是無法尋址的,這時候就需要增加一層網絡轉發,即外網到内網的轉發。實作方式有很多種,我們這裡采用一種叫作NodePort的方式來實作,即k8s将會在每個Node上設定端口,稱為NodePort,通過NodePort端口可以通路到Pod。

環境變量  ---  存在局限性

DNS    

    當有新的Service建立時,就會自動生成一條DNS記錄,以Redis Master Service為例,有一條DNS記錄:

      redis-master   => 10.254.233.212

    使用這種服務發現,k8s叢集必須安裝Cluster DNS

  在Docker中,容器是最小處理機關,增删改查的對象是容器,容器是一種虛拟化技術,容器之間是隔離的,隔離是基于Linux Namespace實作的,Linux核心中提供了6中Linux Namespace隔離的系統調用,如下圖:

k8s實戰讀書筆記

  在k8s中,Pod包含了一個或者多個相關的容器,Pod可以認為是容器的一種延伸擴充,一個Pod也是一個隔離體,而Pod包含一組容器優勢共享的(目前共享的Linux Namespace 包括:PID, Network, IPC和UTS)。除此之外,Pod中的容器可以通路共同的資料卷來實作檔案系統的共享,是以k8s中的資料卷是Pod級别的,而不是容器級别的;

  Pod是容器的集合,容器是真正的執行體。相比原生的容器接口,Pod提供了更高層次的抽象,但是Pod的設計并不是為了運作同一個應用的多個執行個體,而是運作一個應用多個緊密聯系的程式。而每個程式運作在單獨的容器中,以Pod的形式組合成一個應用。相比于在單個容器中運作多個程式,這樣的設計有以下好處:

透明性: 将Pod内的容器向基礎設施可見,底層系統就能向容器提供如程序管理和資源監控等服務,這樣能給使用者帶來極大的便利;

解綁軟體的依賴: 這樣單個容器可以獨立地重建和重新部署,可以實作獨立容器的試試更新;

易用性:使用者不需要運作自己的程序管理器,也不需要負責信号量和退出碼的傳遞等。

高效性:因為底層裝置負責更多的管理,容器因而能更加輕量化;  

  Pod中的所有容器網絡都是共享的,一個Pod中的所有容器中的網絡是一緻的,他們能夠通過本地位址(localhost)通路其他使用者容器的端口。

  在k8s網絡模型中,每一個Pod都擁有一個扁平化共享網絡命名空間的IP,稱為PodIP,通過PodIP,Pod就能夠跨網絡與其他實體機和容器進行通信;

  Pod的生命周期可描述為:首先Pod被建立,Pod被排程到Node進行部署運作。Pod是十分忠誠的,一旦被配置設定到Node後,就不會離開這個Node,直到它被删除,生命周期完結;

Pending: Pod已經被建立,但是一個或者多個容器還未建立,這包括Pod排程階段,以及容器image下載下傳過程;

Running:Pod已經被排程到Node,所有容器已經建立,并且至少一個容器在運作或者重新開機;

Succeeded:Pod中石油容器正常退出;

Failed: Pod中所有容器退出,至少有一個容器是一次退出的。  

  RC和Pod的關聯就是通過Label實作的,Label機制是k8s中很重要的一個設計,通過Label進行對象的弱關聯,可以靈活地進行分類和選擇。

  對于Pod,需要設定Label來進行标示,Label是一系列的Key/Value對, Pod(或者Pod模闆)的定義中通過.metadata.labels設定:

    labels:

      key1: value1

      key2: value2

  對于Replication Controller來說就是通過Label Selector來比對Pod的Label,進而實作關聯關系。在RC的定義中通過.spec.selector來設定Label Selector;

  彈性伸縮:

    #kubectl get replicationcontroller my-nginx

    #kubectl get pod --selector app=nginx

    #kubectl scale replicationcontroller my-nginx --replicas=3

    #kubectl scale replicationcontroller my-nginx [--current-replicas=2] --replicas=1

    #kubectl scale replicationcontroller my-nginx --replicas=0

  自動伸縮:

    在k8s中通過Horizontal Pod Autoscaler來實作Pod的自動伸縮, Horizontal Pod Autoscaler同Replication Controller是一一對應的;Horizontal Pod Autoscaler将定時從平台監控系統中擷取Replication Controller關聯Pod的整體資源使用情況。當政策比對的時候,通過Replication Controller來調整Pod的副本數,實作自動伸縮。

  滾動更新:

    #kubectl rolling-update my-web-v1 -f my-web-v2-rc.yaml --update-period=10s 

    #kubectl rolling-update my-web-v1 -f my-web-v2-rc.yaml --update-period=10s  --rollback   #更新復原

    k8s提供了一種更加簡單的更新Replication Controller 和 Pod 的機制,叫做Deployment

  RC建立的Pod都是長時運作服務,相應的,k8s提供了另一種機制, Job來管理一次性任務的Pod; ----------  兩者在yaml的最大差別是關于Pod的重新開機政策;

繼續閱讀