Kubernetes學習筆記(更新中。。。。)

777_yL發表於2020-11-24

Kubernetes

每個微服務通過Docker進行釋出,隨著業務的發展,系統中遍佈著各種各樣的容器。於是容器的資源排程,部署執行,擴容縮容就是我們需要面臨的問題。

基於 Kubernetes 作為容器叢集的管理平臺被廣泛應用

Kubernetes架構

Kubernetes是用來管理容器叢集的平臺。但它不是直接來管理容器,而是把容器放在pod中,通過管理pod來管間接管理容器。

在這裡插入圖片描述

Master

我們通過 Master 對每個節點 Node 傳送命令。簡單來說,Master 就是管理者,Node 就是被管理者。

Node

Node可以是一臺物理機或者是虛擬機器。在Node上面可以執行多個Pod,Pod是Kubernetes管理的最小單位,同時每個pod可以包含多個容器。

Kubectl

通常我們都是通過 kubectl 對 Kubernetes 下命令的,它通過 APIServer 去呼叫各個程式來完成對 Node 的部署和控制。

API Server

  • APIServer 的核心功能是對核心物件(例如:Pod,Service,RC)的增刪改查操作,同時也是叢集內模組之間資料交換的樞紐。
  • 它包括了常用的 API,訪問(許可權)控制,註冊,資訊儲存(etcd)等功能。在它的下面我們可以看到 Scheduler,它將待排程的 Pod 繫結到 Node 上,並將繫結資訊寫入 etcd 中。
  • etcd 包含在 APIServer 中,用來儲存資源資訊

Controller Manager

Kubenetes是一套自動化執行的系統,那麼就需要有一套管理規則來控制這套系統。Controller Manager 就是這個管理者,或者說是控制者。它包括 8 個 Controller,分別對應著副本,節點,資源,名稱空間,服務等等。

Schedular

將待排程的pod繫結到Node上,並將繫結資訊寫入etcd。

kubelet

kubelet 用於處理 Master 下發到 Node 的任務(即 Scheduler 的排程任務),同時管理 Pod 及 Pod 中的容器。

服務部署

指令部署

kubectl run my-app --image=hub.kaikeba.com/library/myapp:v1 --port=80

yaml檔案部署

kubectl create -f xxx.yml

deployment

apiVersion: apps/v1   # 1.9.0 之前的版本使用 apps/v1beta2,可通過命令kubectl api-versions 檢視
kind: Deployment 	#指定建立資源的角色/型別
metadata: 	 #資源的後設資料/屬性
  name: nginx-deployment	#資源的名字,在同一個namespace中必須唯一
spec:
  replicas: 2 	 #副本數量2
  selector:      #定義標籤選擇器
    matchLabels:
      app: web-server
  template: 	 #這裡Pod的定義
    metadata:
      labels: 	 #Pod的label
        app: web-server
    spec:		 # 指定該資源的內容  
      containers:  
      - name: nginx 	 #容器的名字  
        image: nginx:1.12.1  #容器的映象地址    
        ports:  
        - containerPort: 80  #容器對外的埠

pod

apiVersion: v1
kind: Pod  
metadata:  
  name: pod-redis
  labels:
    name: redis
spec: 
  containers:
  - name: pod-redis
    image: docker.io/redis  
    ports:
    - containerPort: 80	#容器對外的埠

service

apiVersion: v1  
kind: Service  # 指明資源型別是 service
metadata:  
  name: httpd-svc # service 的名字是 httpd-svc
  labels:  
    name: httpd-svc 
spec:  
  ports:  # 將 service 8080 埠對映到 pod 的 80 埠,使用 TCP 協議
  - port: 8080
    targetPort: 80  
    protocol: TCP  
  selector:  
    run: httpd # 指明哪些 label 的 pod 作為 service 的後端

API server

APIServer 的架構從上到下分為四層:

  • **API 層:**主要以 REST 方式提供各種 API 介面,針對 Kubernetes 資源物件的 CRUD 和 Watch 等主要 API,還有健康檢查、UI、日誌、效能指標等運維監控相關的 API。
  • **訪問控制層:**負責身份鑑權,核准使用者對資源的訪問許可權,設定訪問邏輯(Admission Control)。
  • **登錄檔層:**選擇要訪問的資源物件。PS:Kubernetes 把所有資源物件都儲存在登錄檔(Registry)中,例如:Pod,Service,Deployment 等等。
  • **etcd 資料庫:**儲存建立副本的資訊。用來持久化 Kubernetes 資源物件的 Key-Value 資料庫。

在這裡插入圖片描述

Controller Manager

Kubernetes 需要管理叢集中的不同資源,所以針對不同的資源要建立不同的 Controller。

每個 Controller 通過監聽機制獲取 APIServer 中的事件(訊息),它們通過 API Server 提供的(List-Watch)介面監控叢集中的資源,並且調整資源的狀態。

可以把它想象成一個盡職的管理者,隨時管理和調整資源。比如 MySQL 所在的 Node 意外當機了,Controller Manager 中的 Node Controller 會及時發現故障,並執行修復流程。

在部署了成百上千微服務的系統中,這個功能極大地協助了運維人員。從此可以看出,Controller Manager 是 Kubernetes 資源的管理者,是運維自動化的核心。

它分為 8 個 Controller,上面我們介紹了 Replication Controller,這裡我們把其他幾個都列出來,就不展開描述了。

img

Controller Manager 中不同的 Controller 負責對不同資源的監控和管理

Scheduler 與 kubelet

在這裡插入圖片描述

Scheduler 的作用是,將待排程的 Pod 按照演算法和策略繫結到 Node 上,同時將資訊儲存在 etcd 中。

如果把 Scheduler 比作排程室,那麼這三件事就是它需要關注的,待排程的 Pod、可用的 Node,排程演算法和策略。

簡單地說,就是通過排程演算法/策略把 Pod 放到合適的 Node 中去。此時 Node 上的 kubelet 通過 APIServer 監聽到 Scheduler 產生的 Pod 繫結事件,然後通過 Pod 的描述裝載映象檔案,並且啟動容器。

也就是說 Scheduler 負責思考,Pod 放在哪個 Node,然後將決策告訴 kubelet,kubelet 完成 Pod 在 Node 的載入工作。

說白了,Scheduler 是 boss,kubelet 是幹活的工人,他們都通過 APIServer 進行資訊交換。

img

Scheduler 與 kubelet 協同工作圖

Service

服務部署使用K8s來進行部署,如何實現叢集 ?

複製多個pod實現負載均衡即可

多個pod之間如何進行訪問?

k8s提供了一個service資源物件,實現多個pod之間的請求轉發。

在 Kubernetes 中的 Service 定義了一個服務的訪問入口地址(IP+Port)。Pod 中的應用通過這個地址訪問一個或者一組 Pod 副本。

Service 與後端 Pod 副本叢集之間是通過 Label Selector 來實現連線的。Service 所訪問的這一組 Pod 都會有同樣的 Label,通過這樣的方法知道這些 Pod 屬於同一個組。(一般一組業務(pod)對應一個service

在這裡插入圖片描述
通過 kubectl get svc 檢視service資源物件

在這裡插入圖片描述

這裡的cluster-ip是由kubernetes自動分配的。當一個pod需要訪問其他的pod的時候就需要通過Service的Cluster-ip和Port。也就是說CLuster-ip和Pod是Kubernetes叢集的內部地址,是提供給叢集內的Pod之間訪問使用的,外部系統是無法通過這個Cluster-ip來訪問Kubernetes中的應用。

service如何實現對pod的負載均衡?

通過iptables ,預設是輪詢。

KubeProxy

在Kubenetes叢集上的每個Node上都會執行一個Kube-proxy服務程式,我們可以把這個程式看作Service的負載均衡器,其核心功能是將到Service的請求轉發到後端的多個Pod上。

此外,Service 的 Cluster-IP 與 NodePort 是 kube-proxy 服務通過 iptables 的 NAT 轉換實現的。kube-proxy 在執行過程中動態建立與 Service 相關的 iptables 規則。

由於 iptables 機制針對的是本地的 kube-proxy 埠,所以在每個 Node 上都要執行 kube-proxy 元件。
在這裡插入圖片描述

Ingress

在這裡插入圖片描述

Ingress 是一個反向代理服務,底層就是Nginx,是Kubernetes對nginx做了擴充套件開發;因此Ingress具有動態配置的的能力;

Ingress作用是對後端ServiceVIP提供反向代理服務;使得對外使用者只有一個訪問的入口,所有請求都必須經過INgress進行轉發,轉發給後端Service,然後由Service把請求轉發給POD服務。

All in all

Kubernetes是用來管理容器叢集的,Master作為管理者,包括API server ,Scheduler、Controller Manager。

Node作為副本部署的載體,包含多個Pod,每個Pod又包含多個容器(container)。使用者通過kubectl 給Master中的APIServer下部署命令。

命令主體是以“.yaml”結尾的配置檔案,包含副本的型別,副本個數,名稱,埠,模版等資訊。

APIServer 接受到請求以後,會分別進行以下操作:許可權驗證(包括特殊控制),取出需要建立的資源,儲存副本資訊到etcd。

APIServer 和 Controller Manager,Scheduler 以及 kubelete 之間通過 List-Watch 方式通訊(事件傳送與監聽)。

Controller Manager 通過 etcd 獲取需要建立資源的副本數,交由 Scheduler 進行策略分析。

最後 kubelet 負責最終的 Pod 建立和容器載入。部署好容器以後,通過 Service 進行訪問,通過 cAdvisor 監控資源。

常用指令

檢視某分支下的pod

kubectl get pod -n dev-core

檢視pod內某個容器的日誌

kubectl logs <容器名> -n dev-core

檢視分支下的ingress

kubectl get ingress -n dev-core

部署指令

kubectl run myapp –image=映象地址 –port=80 容器埠

以yaml檔案部署

kubectl create -f xxx.yaml

查詢資源物件:

  • kubectl get pod
  • kubectl get deployment
  • kubectl get rs
  • kubectl get pod -o wide

進入dev-core中pod的容器內部(前提是該pod中只有一個容器)

 kubectl exec -it nvhl-pcis-elasticsearch-impl-546f4d649c-rpwsj-n dev-core -- /bin/bash

檢視資源物件描述資訊

kubectl describe pod/ContainerName  -n dev-core

相關文章