十、Kubernetes 進階之核心組件篇

在K8S章節剛開始我們就介紹了里面的核心組件與架構圖,但對于它們只是有一個很淺的認知,只知道它是干嘛的,對于它們都做了哪些事情比較模糊,本章節就對幾個核心組件做個梳理介紹!

1、Master和Node

在正式梳理組件之前,再次回顧下Master節點和Node節點的功能,以及組件分配。

  • 架構圖

    image.png
  • Master

    • Master節點是K8S集群中的控制節點,負責整個集群的管理和控制,可以做成高可用,防止節點掛掉導致集群不可用。
    • 其中有一些關鍵的組件:比如API Server,Controller Manager,Scheduler等
  • Node

    • Node會被Master分配一些工作負載,當某個Node不可用時,會將工作負載轉移到其他Node節點上。
    • Node上有一些關鍵的組件:kubelet,kube-proxy,docker等

2、 Kubeadm

搭建K8S有很多種方式,Kubeadm只是其中一種方式,適合個人搭建集群使用,這里要介紹的也就是Kubeadm的工作流程。

Kubeadm分為2個步驟:

  • kubeadm init

    • 用于初始化K8S集群中的Master節點

    • 工作流程

      image.png
    • 流程說明

      • preflight

        • 進行一系列檢查[init之前的檢查],以確定這臺機器可以部署kubernetes
        • kubeadm版本與要安裝的kubernetes版本的檢查
        • kubernetes安裝的系統需求檢查[centos版本、cgroup、docker等]
        • 用戶權限、主機環境、端口是否開放、swap是否關閉等
      • certs

        • 生成kubernetes對外提供服務所需要的各種證書可對應目錄,也就是生成私鑰和數字證書。證書目錄:/etc/kubernetes/pki/
        • 自建ca,生成ca.key和ca.crt
        • apiserver的私鑰與公鑰證書
        • apiserver訪問kubelet使用的客戶端私鑰與證書
        • sa.key和sa.pub
        • etcd相關私鑰和數字證書
      • kubeconfig

        • 為其他組件生成訪問kube-ApiServer所需的配置文件 xxx.conf,配置目錄:/etc/kubernetes/

          image.png
  + init完成之后我們還需要創建 .kube 文件夾,復制一個配置文件到該目錄下,這個步驟就是讓當前節點擁有與apiServer打交道的權限。
  + kubeconfig中包含了cluster、user和context信息。通過kubectl config view查看

+ control-plane

  + 為master生成Pod配置文件,這些組件會被master節點上的kubelet讀取到,并且自動創建對應資源,Pod的文件目錄:/etc/kubernetes/manifests/
  + 這些pod由kubelet直接管理,是靜態pod,直接使用主機網絡
  + kubelet讀取manifests目錄并管理各控制平臺組件pod的啟動與停止
    + 一旦這些 YAML 文件出現在被 kubelet 監視的/etc/kubernetes/manifests/目錄下,kubelet就會自動創建這些yaml文件定義的pod,即master組件的容器。master容器啟動后,kubeadm會通過檢查localhost:6443/healthz這個master組件的健康狀態檢查URL,等待master組件完全運行起來
  + 要想修改這些pod,直接修改manifests下的yaml文件即可
  + 這個步驟會下載鏡像,我們前面已經通過手動下載國內鏡像然后打Tag的方式下載好了,所以這個步驟會進行的很快,否則直接從國外地址下會很慢

+ upload-config

  + 將ca.crt等 Master節點的重要信息,通過ConfigMap的方式保存在etcd中,供后續部署node節點使用

+ bootstrap-token

  + 為集群生成一個bootstrap token,設定當前node為master,master節點將不承擔工作負載,當然也可以調整讓Master承擔工作負載。

+ addons

  + 安裝默認插件,kubernetes默認kube-proxy和DNS兩個插件是必須安裝的,dns插件安裝了會出于pending狀態,要等網絡插件安裝完成,比如calico
    + 通過kubectl get daemonset -n kube-system
    + 可以看到kube-proxy和calico[或者其他網絡插件]
  • kubeadm join

    • 用于將worker節點加入K8S集群中
    image.png
  • 流程說明

    • 通過discovery-token-ca-cert-hash驗證master身份

      # 可以計算出來,在worker節點上執行
      openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -pubkey | openssl rsa -pubin -
      outform DER 2>/dev/null | sha256sum | cut -d' ' -f1
      # 最終hash的值
      909adc03d6e4bd676cfc4e04b864530dd19927d8ed9d84e224101ef38ed0bb96
      
    • 通過token讓master可以驗證node

      # 在master上節點上,可以查看對應的token
      kubectl get secret -n kube-system | grep bootstrap-token
      # 得到token的值
      kubectl get secret/bootstrap-token-kggzhc -n kube-system -o yaml
      # 對token的值進行解碼
      echo NHRzZHp0Y2RidDRmd2U5dw== | base64 -d
      # 最終token的值
      kggzhc.4tsdztcdbt4fwe9w
      
    • 因為kubeadm的 join 信息是有時效的,又或者忘了join信息,也可以重新生成

      # 重新生成 join 信息,默認有效期24小時,若想久一些可以結合--ttl參數,設為0則用不過期
      kubeadm token create --print-join-command
      

3、kubectl

kubectl 是一個命令行接口,用于對 Kubernetes 集群運行命令。

kubectl 會在 $HOME/.kube 目錄中尋找一個名為 config 的文件,通過它就可以與apiServer打交道了。

3.1 kubectl 語法

kubectl [command] [TYPE] [NAME] [flags]

其中 commandTYPENAMEflags 分別是:

  • command:指定要對一個或多個資源執行的操作,例如 creategetdescribedelete

  • TYPE:指定資源類型。資源類型不區分大小寫,可以指定單數、復數或縮寫形式。例如,以下命令輸出相同的結果:

    kubectl get pod <pod_name>
    kubectl get pods <pod_name>
    kubectl get po <pod_name>
    
  • NAME:指定資源的名稱。名稱區分大小寫。如果省略名稱,則顯示所有資源的詳細信息 kubectl get pods

在對多個資源執行操作時,可以按類型和名稱指定每個資源,或指定一個或多個文件:

  • 要按類型和名稱指定資源:
    • 要對所有類型相同的資源進行分組,請執行以下操作:TYPE1 name1 name2 name<#>
      例子:kubectl get pod example-pod1 example-pod2
    • 分別指定多個資源類型:TYPE1/name1 TYPE1/name2 TYPE2/name3 TYPE<#>/name<#>
      例子:kubectl get pod/example-pod1 replicationcontroller/example-rc1
  • 用一個或多個文件指定資源:-f file1 -f file2 -f file<#>
    • 使用 YAML 而不是 JSON 因為 YAML 更容易使用,特別是用于配置文件時。
      例子:kubectl get pod -f ./pod.yaml
  • flags: 指定可選的參數。例如,可以使用 -s-server 參數指定 Kubernetes API 服務器的地址和端口。
    • 指定參數會覆蓋默認值和任何相應的環境變量。

4、ApiServer

API Server 為 api 對象驗證并配置數據,包括 pods、 services、 replicationcontrollers 和其它 api 對象。API Server 提供 REST 操作和到集群共享狀態的前端,是集群內各個功能模塊之間數據交互和通信的中心樞紐,是整個系統的數據總線和數據中心。所有其他組件通過它進行交互。

API Server通過kube-apiserver的進程提供服務,運行在master節點上

4.1 REST API設計

K8S交互實際是使用 REST API 進行的,kubectl 命令底層實際也是通過這種方式調用。

image.png

如果想要用 http 的方式調用 K8S 的服務,需要進行如下操作:

  • 啟用端口

    • kubeadm安裝方式
      • 其他安裝方式怎么啟用我也沒查過

    默認情況下,insecure-port=0,表示不啟用

    image.png
  • 應用修改

    [root@master-kubeadm-k8s ~]# kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
    pod/kube-apiserver created
    
    # 可以看到8088端口已經開始監聽
    [root@master-kubeadm-k8s ~]# lsof -i tcp:8088
    COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    kube-apis 30427 root    3u  IPv4 285948      0t0  TCP master-kubeadm-k8s:radan-http (LISTEN)
    
  • 測試

    可以一個一個去試試看

    curl localhost:8088
    curl localhost:8088/api
    curl localhost:8088/api/v1
    curl localhost:8088/api/v1/pods
    curl localhost:8088/api/v1/services

    image.png

4.2 集群安全機制

對于k8s集群的訪問操作,都是通過api server的rest api來實現的,難道所有的操作都允許嗎?當然不行,這里就涉及到 認證、授權和準入控制 等操作。

請求到達 API 服務器后會經過幾個階段,具體說明如圖:

image.png

4.2.1 傳輸層安全

在典型的 Kubernetes 集群中,API 通過 443 端口提供服務。 API 服務器會提供一份證書。 該證書一般是自簽名的, 所以用戶機器上的 $USER/.kube/config 目錄通常 包含該 API 服務器證書的根證書,用來代替系統默認根證書。 當用戶使用 kube-up.sh 創建集群時,該證書通常會被自動寫入用戶的 $USER/.kube/config。 如果集群中存在多個用戶,則創建者需要與其他用戶共享證書。

4.2.2 認證(Authentication)

說白了,就是如何來識別客戶端的身份,

認證可以分為兩個維度來說

第一個維度

K8s集群提供了3種識別客戶端身份的方式

  • HTTPS證書認證
    • 基于CA根證書簽名的雙向數字證書認證方式
  • HTTP Token認證
    • 通過一個Token來識別合法用戶
  • HTTP Base認證
    • 通過用戶名+密碼的方式認證

第二個維度

系統組件要想和apiServer進行認證

  • Service Account
    • 創建service Account會再默認的自動創建一個secret,這個secret會被自動加入到系統中的Pod,上一章我們也演示過了

4.2.3 授權(Authorization)

Kubernetes 使用 API 服務器 授權 API 請求。它根據所有策略評估所有請求屬性來決定允許或拒絕請求。 一個 API 請求的所有部分必須被某些策略允許才能繼續。這意味著默認情況下拒絕權限。

4.2.3.1 授權方式
  • Node

    • 一個專用授權程序,根據計劃運行的 pod 為 kubelet 授予權限
  • ABAC

    • 基于屬性的訪問控制(ABAC)定義了一種訪問控制范例,通過使用將屬性組合在一起的策略,將訪問權限授予用戶。
    • 策略可以使用任何類型的屬性(用戶屬性,資源屬性,對象,環境屬性等)
  • RBAC

    • 基于角色的訪問控制(RBAC)是一種基于企業內個人用戶的角色來管理對計算機或網絡資源的訪問的方法。
    • 在此上下文中,權限是單個用戶執行特定任務的能力,例如查看,創建或修改文件。
    • 當指定的 RBAC(基于角色的訪問控制)使用 rbac.authorization.k8s.io API 組來驅動授權決策時,允許管理員通過 Kubernetes API 動態配置權限策略。
    • 要啟用 RBAC,使用 --authorization-mode = RBAC 啟動 apiserver 。
  • Webhook

    • WebHook 是一個 HTTP 回調:發生某些事情時調用的 HTTP POST;通過 HTTP POST 進行簡單的事件通知。
    • 實現 WebHook 的 Web 應用程序會在發生某些事情時將消息發布到 URL。

我們主要看看最常用的 RBAC 授權方式即可

4.2.3.2 RBAC授權
  • 資源分類
    • Role和ClusterRole
      • 在 RBAC API 中,一個角色包含一組相關權限的規則。
      • 權限是純粹累加的(不存在拒絕某操作的規則)。
      • 角色可以用 Role 來定義到某個命名空間上, 或者用 ClusterRole 來定義到整個集群作用域。
    • RoleBinding和ClusterRoleBinding
      • 角色綁定(RoleBinding)是將角色中定義的權限賦予一個或者一組用戶。
      • 它包含若干主體(用戶,組和服務賬戶)的列表和對這些主體所獲得的角色的引用。
      • 可以使用 RoleBinding在指定的命名空間中執行授權, 或者在集群范圍的命名空間使用 ClusterRoleBinding 來執行授權。
  • 圖解說明
    • subjects可以理解為是一個用戶
    • RoleBinding、ClusterBinding是用戶與Role、ClusterRole直接的關聯關系
    • Role、ClusterRole又會關聯到資源以及權限
    • 整張圖理解下來就是:一個用戶綁定了什么角色,這個角色可以操作哪些資源
image.png

Role和RoleBinding

  • 一個 Role 只可以用來對某一命名空間中的資源賦予訪問權限

  • 一個 RoleBinding 可以引用同一的命名空間中的 Role

  • 通過之前章節中的 NFS 插件的 rbac.yaml 文件來說明

    下面的例子中就表示

    將名稱為:leader-locking-nfs-provisioner 的 Role 綁定到名為:nfs-provisioner 的ServiceAccount 資源上,這樣,ServiceAccount就擁有了對 ‘endpoints’ 資源的操作權限

    apiVersion: rbac.authorization.k8s.io/v1  # rbac版本
    kind: Role                                    # 資源類型為 Role
    metadata:
      # 此處的 "namespace" 被省略掉是因為使用的 default 命名空間
      name: leader-locking-nfs-provisioner        # Role資源名稱
    rules:                                        # 配置權限
      - apiGroups: [""]                           # k8s 的 api 太多了,因此分 group, "" 表示指定核心 API 組
        resources: ["endpoints"]              # 表示當前Role綁定的資源是什么
        verbs: ["get", "list", "watch", "create", "update", "patch"] # 表示對endpoints擁有什么樣的操作權限, 根據自己的需要來確定如何填寫,全部操作支持用 ["*"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding                         # 綁定角色的資源
    metadata:
      name: leader-locking-nfs-provisioner        # 資源名稱
    subjects:
      - kind: ServiceAccount                  # 使用該角色的資源類型
        name: nfs-provisioner                 # 資源類型名稱
        namespace: default
    roleRef:                                  # 引用綁定的角色
      kind: Role                              # 資源類型
      name: leader-locking-nfs-provisioner        # Role資源的名稱
      apiGroup: rbac.authorization.k8s.io     # 指定api組
    
  • RoleBinding 也可以引用 ClusterRole,對 ClusterRole 所定義的、位于 RoleBinding 命名空間內的資源授權。 這樣開發者就可以在整個集群中定義一組通用的角色,然后在多個命名空間中重用它們。

ClusterRole和ClusterRoleBinding

  • ClusterRole 可以授予的權限和 Role 相同, 但是因為 ClusterRole 屬于集群范圍,所以它也可以授予以下訪問權限:

    • 集群范圍資源 (比如 nodes)
    • 非資源端點(比如 “/healthz”)
    • 跨命名空間訪問的有命名空間作用域的資源(如 Pods),比如運行命令kubectl get pods --all-namespaces 時需要此能力
  • ClusterRoleBinding 可用來在集群級別或對所有命名空間執行授權

  • 同樣通過NFS的rbac.yaml文件說明

    下面的例子就表示

    將名稱為:nfs-provisioner-runner 的ClusterRole 綁定到名稱為:nfs-provisioner 的 ServiceAccount 資源上,這樣,ServiceAccount 資源就擁有了操作任意命名空間中下面定義的資源的權限

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      # 此處的 "namespace" 被省略掉是因為 ClusterRoles 是沒有命名空間的。
      name: nfs-provisioner-runner
    rules:                                        # 這里讓當前ClusterRole擁有多個資源的操作權限
      - apiGroups: [""]
        resources: ["persistentvolumes"]
        verbs: ["get", "list", "watch", "create", "delete"]
      - apiGroups: [""]
        resources: ["persistentvolumeclaims"]
        verbs: ["get", "list", "watch", "update"]
      - apiGroups: ["storage.k8s.io"]
        resources: ["storageclasses"]
        verbs: ["get", "list", "watch"]
      - apiGroups: [""]
        resources: ["events"]
        verbs: ["create", "update", "patch"]
      - apiGroups: [""]
        resources: ["services", "endpoints"]
        verbs: ["get"]
      - apiGroups: ["extensions"]
        resources: ["podsecuritypolicies"]
        resourceNames: ["nfs-provisioner"]
        verbs: ["use"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: run-nfs-provisioner
    subjects:
      - kind: ServiceAccount
        name: nfs-provisioner
        namespace: default
    roleRef:
      kind: ClusterRole
      name: nfs-provisioner-runner
      apiGroup: rbac.authorization.k8s.io
    
  • 注意

    • 不能修改綁定對象所引用的 RoleClusterRole ,改變 roleRef 會導致驗證錯誤。

    • 想要改變現有綁定對象中 roleRef 字段的內容,必須刪除并重新創建綁定對象。

    • 這種限制有兩個主要原因:

      • 關于不同角色的綁定是完全不一樣的。更改 roleRef 需要刪除/重建綁定,確保要賦予綁定的完整主體列表是新的角色(而不是只是啟用修改 roleRef 在不驗證所有現有主體的情況下的,應該授予新角色對應的權限)。

      • 使得 roleRef 不可以改變現有綁定主體用戶的 update 權限, 可以讓它們能夠管理主體列表,而不能更改授予這些主體相關的角色。

4.2.4 準入控制(Admission Control)

準入控制 是能夠修改或拒絕請求的軟件模塊。 作為授權模塊的補充,準入控制模塊會訪問被創建或更新的對象的內容。 它們作用于對象的創建,刪除,更新和連接(proxy)階段,但不包括對象的讀取。可以同時配置多個準入控制器,它們會按順序依次被調用。

除了拒絕請求外,準入控制器還可以為對象設置復雜的默認值。

與認證和授權模塊不同的是,如果任一個準入控制器拒絕請求,那么整個請求會立即被拒絕。

4.2.4.1 準入控制插件

準入控制器是一段代碼,它會在請求通過認證和授權之后、對象被持久化之前攔截到達 API 服務器的請求。

準入控制器可以執行 “驗證” 和/或 “變更” 操作。變更(mutating)控制器可以修改被其接受的對象;驗證(validating)控制器則不行。

準入控制過程分為兩個階段。第一階段,運行變更準入控制器。第二階段,運行驗證準入控制器。

  • 準入控制模塊

    • AlwaysPullImages

      • 該準入控制器會修改每一個新創建的 Pod 的鏡像拉取策略為 Always
    • DefaultStorageClass

      • 該準入控制器監測沒有請求任何特定存儲類的 PersistentVolumeClaim 對象的創建,并自動向其添加默認存儲類
    • AlwaysAdmit

      • 該準入控制器會允許所有的 pod 接入集群。在 Kubernetes v1.13 已廢棄
    • AlwaysDeny

      • 拒絕所有的請求。由于沒有實際意義,在 Kubernetes v1.13 已廢棄
    • ....

5、Scheduler

Scheduler通過 kubernetes 的 watch 機制來發現集群中新創建且尚未被調度到 Node 上的 Pod。

Scheduler會將發現的每一個未調度的 Pod 調度到一個合適的 Node 上來運行。

對每一個新創建的 Pod 或者是未被調度的 Pod,kube-scheduler 會選擇一個最優的 Node 去運行這個 Pod。然而,Pod 內的每一個容器對資源都有不同的需求,而且 Pod 本身也有不同的資源需求。所以Pod 在被調度到 Node 上之前,會根據這些特定的資源調度需求,需要對集群中的 Node 進行一次過濾。

5.1 kube-scheduler 調度流程

kube-scheduler 給一個 pod 做調度選擇包含兩個步驟:

  • 過濾

    • 過濾階段會將所有滿足 Pod 調度需求的 Node 選出來。
    • 在過濾之后,得出一個 Node 列表,里面包含了所有可調度節點
    • 通常情況下,這個 Node 列表包含不止一個 Node。如果是空的,代表這個 Pod 不可調度。
  • 打分

    • 在打分階段,調度器會為 Pod 從所有可調度節點中選取一個最合適的 Node。根據當前啟用的打分規則,調度器會給每一個可調度節點進行打分。
    • 最后,kube-scheduler 會將 Pod 調度到得分最高的 Node 上。
    • 如果存在多個得分最高的 Node,kube-scheduler 會從中隨機選取一個。

5.2 Scheduler結構圖

image.png
  • scheduler會監聽ApiServer是否有Pod相關的請求,若有則會獲取請求到Pod等待隊列中
  • Node相關的請求是無法通過ApiServer監聽到的,但是當Node加入集群后會將自身信息存到ETCD中,所以scheduler也可以獲取到。
  • scheduler會通過預選策略篩選和優選策略打分,找到最合適的Node

5.3 預選策略(Predicates)

預選策略會進行初步篩選,找出符合條件的節點

  • PodFitsHostPorts:檢查一個節點是否有Pod所需且空閑的端口(網絡協議類型) 。
  • PodFitsHost:檢查一個Pod是否指定了一個特定的節點的主機名。
  • PodFitsResources:檢查節點是否有空閑的資源(比如CPU和內存) 以滿足Pod的要求。
  • PodMatchNodeSelector: 檢查節點是否有Pod所指定的標簽
  • ........

5.4 優選策略(Priorities)

  • NodeAffinityPriority:優先選擇親和性高的節點。

  • ImageLocalityPriority: 優先選擇本地已經有鏡像存在的。

  • BalancedResourceAllocation:以平衡節點的資源使用情況為優先。

  • .......

5.5 演示

  • 不修改策略的情況

    • 準備YAML文件

      • base-scheduler-node.yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: scheduler-node
      spec:
        selector:
          matchLabels:
            app: scheduler-node
        replicas: 1
        template:
          metadata:
            labels:
              app: scheduler-node
          spec:
            containers:
            - name: scheduler-node
              image: nginx
              ports:
              - containerPort: 80
      
    • 創建資源

      [root@master-kubeadm-k8s scheduler]# kubectl apply -f base-scheduler-node.yaml
      deployment.apps/scheduler-node created
      
    • 查看資源

      正常是可以直接創建的,但無法得知它會分配到哪個節點

      [root@master-kubeadm-k8s scheduler]# kubectl get pods
      NAME                              READY   STATUS    RESTARTS   AGE
      scheduler-node-58474cbbb7-m57xm   1/1     Running   0          23s
      
  • 使用調度策略的情況

    • 準備YAML文件

      • scheduler-node.yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: scheduler-node
      spec:
        selector:
          matchLabels:
            app: scheduler-node
        replicas: 1
        template:
          metadata:
            labels:
              app: scheduler-node
          spec:
            containers:
            - name: scheduler-node
              image: nginx
              ports:
              - containerPort: 80
            affinity:                     # 根據親和性篩選,親和性就是更愿意運行在什么樣的環境下
              nodeAffinity:               # 根據節點的親和性篩選
                requiredDuringSchedulingIgnoredDuringExecution:   # required表示必須滿足的條件
                  nodeSelectorTerms:      # 表示節點的標簽必須要有 beta.kubernetes.io/arch:amd641
                  - matchExpressions:
                    - key: beta.kubernetes.io/arch
                      operator: In
                      values:
                      - amd641
                preferredDuringSchedulingIgnoredDuringExecution:  # preferred表示更愿意選擇的條件,但不強制要求
                - weight: 1
                  preference:
                    matchExpressions:
                    - key: disktype
                      operator: NotIn
                      values:
                      - ssd
      
    • 部署資源前先查看node信息

      節點中只有標簽 beta.kubernetes.io/arch=amd64的,沒有值為amd641的,所以如果按上面的YAML文件配置,它是無法部署成功的

      image.png
  • 創建資源

    [root@master-kubeadm-k8s scheduler]# kubectl apply -f scheduler-node.yaml
    deployment.apps/scheduler-node created
    
  • 查看資源

    # 發現是Pending狀態
    [root@master-kubeadm-k8s scheduler]# kubectl get pods
    NAME                              READY   STATUS      RESTARTS   AGE
    scheduler-node-795b7f967f-fxr2r   0/1     Pending     0          17s
    
    image.png
> 這里說沒用匹配到,因為沒有滿足我們條件的節點
  • 修改YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: scheduler-node
    spec:
      selector:
        matchLabels:
          app: scheduler-node
      replicas: 1
      template:
        metadata:
          labels:
            app: scheduler-node
        spec:
          containers:
          - name: scheduler-node
            image: nginx
            ports:
            - containerPort: 80
          affinity: 
            nodeAffinity: 
              requiredDuringSchedulingIgnoredDuringExecution: 
                nodeSelectorTerms: 
                - matchExpressions:
                  - key: beta.kubernetes.io/arch
                    operator: In
                    values:
                    - amd64             # 將這里改成amd64,節點的標簽是有這個值的
              preferredDuringSchedulingIgnoredDuringExecution: 
              - weight: 1
                preference:
                  matchExpressions:
                  - key: disktype
                    operator: NotIn
                    values:
                    - ssd
    
  • 重新創建資源并查看

    [root@master-kubeadm-k8s scheduler]# kubectl apply -f scheduler-node.yaml
    deployment.apps/scheduler-node created
    
    # 發現已經正常創建了
    [root@master-kubeadm-k8s scheduler]# kubectl get pods
    NAME                              READY   STATUS    RESTARTS   AGE
    scheduler-node-64574dd96d-x77h9   1/1     Running   0          15s
    

更多的內容可以到官網查看,這里不深入了

6、kubelet

  • kubelet 是在每個 Node 節點上運行的主要 “節點代理”。用于處理master節點下發到本節點的任務。

  • 它可以使用主機名(hostname)向 apiserver 注冊節點;可以提供用于覆蓋主機名的參數;還可以執行特定于某云服務商的邏輯。

  • kubelet 是基于 PodSpec 來工作的。每個 PodSpec 是一個描述 Pod 的 YAML 或 JSON 對象。

  • kubelet 通過接受各種機制(主要是通過 apiserver)提供的一組 PodSpec,并確保這些 PodSpec 中描述的容器處于運行狀態且運行狀況良好。

  • 每個kubelet進程會在API Server上注冊節點自身信息,定期向Master節點匯報節點資源的使用情況,并通過cAdvisor監控容器和節點資源。

  • kubelet 不管理不是由 Kubernetes 創建的容器。

  • 在k8s集群中,每個Node上都會啟動一個kubelet服務進程,

7、kube-proxy

Kubernetes proxy在每個節點上運行。

proxy反映了每個節點上 Kubernetes API 中定義的服務,并且可以執行簡單的 TCP、UDP 和 SCTP 流轉發,或者在一組后端進行循環 TCP、UDP 和 SCTP 轉發。

它是Service的透明代理兼負載均衡器,核心功能是將某個Service的訪問請求轉發到后端的多個Pod實例上

8、kube-controller-manager

Kubernetes 控制器管理器是一個守護進程,嵌入了 Kubernetes 附帶的核心控制循環。控制回路是一個永不休止的循環,用于調節系統狀態。

它通過 apiserver 監視集群的共享狀態,并嘗試進行更改以將當前狀態轉為所需狀態。現今,Kubernetes 自帶的控制器包括副本控制器,節點控制器,命名空間控制器和serviceaccounts 控制器。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。