k8s-核心元件

little小新發表於2024-07-03

核心元件組成

Kubernetes 主要由以下幾個核心元件組成:
- etcd :儲存整個叢集的狀態
- API Server:提供了資源操作的唯一入口,並提供認證、授權、訪問控制、API註冊和發現等機制
- Controller Manager:負責維護叢集的狀態,如故障檢測、自動擴充套件、滾動更新等
- Scheduler:負責資源的排程、按照預定的排程策略將pod排程到相應的節點上
- Kubelet:負責維護容器的生命週期、同時也負責Volume(CVI)和網路(CNI)的管理
- Container Runtime:負責映象管理以及pod和容器的真正執行(CRI)
- Kube-proxy:負責為Service提供cluster內部的服務發現和負載均衡

k8s-核心元件

元件之間的通訊

API Server 負責 etcd 儲存的所有操作,且只有 API Server 才直接操作 etcd 叢集

Kubernetes 多元件之間的通訊原理為:
- API Server 負責 etcd 儲存的所有操作,且只有 API Server 才直接操作 etcd 叢集
- API Server 對內(叢集中的其他元件)和對外(使用者)提供統一的 REST API,其他元件均透過 API Server 進行通訊
    - Controller Manager、Scheduler、Kube-proxy 和 Kubelet 等均透過 API Server watch API 監測資源變化情況,並對資源作相應的操作
    - 所有需要更新資源狀態的操作均透過 API Server 的 REST API 進行
- API Server 也會直接呼叫 Kubelet API(如 logs, exec, attach 等),預設不校驗 Kubelet 證書,但可以透過 --kubelet-certificate-authority 開啟(而 GKE 透過 SSH 隧道保護它們之間的通訊)


# 比如建立一個pod的流程:
1.使用者透過 REST API 建立一個 Pod
2.API Server 將其寫入 etcd
3.Scheduluer 檢測到未繫結 Node 的 Pod,開始排程並更新 Pod 的 Node 繫結
4.Kubelet 檢測到有新的 Pod 排程過來,透過 Container Runtime 執行該 Pod
5.Kubelet 透過 Container Runtime 取到 Pod 狀態,並更新到 API Server 中

各元件使用的埠號

k8s-核心元件

kube-apiserver

核心功能:資源的操作入口
    - 提供叢集管理的REST API介面、包括認證授權、准入控制、資料校驗以及叢集狀態變更等
    - 負責其他模組之間的資料互動和通訊的樞紐。
    - 只有 ApiServer 能直接操作 Etcd,其他模組均需要透過它來查詢或修改資料
    

REST API

kube-apiserver 支援同時提供 https(預設監聽在 6443 埠)和 http API(預設監聽在 127.0.0.1 的 8080 埠),其中 http API 是非安全介面,不做任何認證授權機制,不建議生產環境啟用。兩個介面提供的 REST API 格式相同,參考 Kubernetes API Reference 檢視所有 API 的呼叫格式

k8s-核心元件

在實際使用中,通常透過 kubectl 來訪問 apiserver,也可以透過 Kubernetes 各個語言的 client 庫來訪問 apiserver。
在使用 kubectl 時,開啟除錯日誌也可以看到每個 API 呼叫的格式,比如
$ kubectl --v=8 get pods


# 查詢 Kubernetes API 支援的 API 版本
$ kubectl api-versions

admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
apps/v1beta1
apps/v1beta2
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1
autoscaling/v2beta1
batch/v1
batch/v1beta1
certificates.k8s.io/v1beta1
events.k8s.io/v1beta1
extensions/v1beta1
metrics.k8s.io/v1beta1
networking.k8s.io/v1
policy/v1beta1
rbac.authorization.k8s.io/v1
rbac.authorization.k8s.io/v1beta1
scheduling.k8s.io/v1beta1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1

# 叢集支援的API版本
$ kubectl api-versions | grep apps
apps/v1
apps/v1beta1
apps/v1beta2

# 所有支援的資源
$ kubectl api-resources

# 獲取特定組 apps 的資源
$ kubectl api-resources --api-group=storage.k8s.io
NAME                SHORTNAMES   APIGROUP         NAMESPACED   KIND
storageclasses      sc           storage.k8s.io   false        StorageClass
volumeattachments                storage.k8s.io   false        VolumeAttachment

# 資源詳細解釋
$ kubectl explain svc
$ kubectl explain svc.spec

kube-controller-manager

核心功能:是 Kubernetes 的大腦,透過與apiserver互動來實現整個叢集的狀態,確保叢集處於預期的狀態

圖中cloud-controller-manager 在 Kubernetes 啟用 Cloud Provider 的時候才需要,用來配合雲服務提供商的控制

k8s-核心元件

kube-controller-manager 由以下的控制器組成

每個控制器的作用參考:

Replication Controller
Node Controller
CronJob Controller
Daemon Controller
Deployment Controller
Endpoint Controller
Garbage Collector
Namespace Controller
Job Controller
Pod AutoScaler
RelicaSet
Service Controller
ServiceAccount Controller
StatefulSet Controller
Volume Controller
Resource quota Controller



***

kube-controller-manager 由一系列的控制器組成,這些控制器可以劃分為三組

必須啟動的控制器
EndpointController
ReplicationController
PodGCController
ResourceQuotaController
NamespaceController
ServiceAccountController
GarbageCollectorController
DaemonSetController
JobController
DeploymentControlle
ReplicaSetController
HPAController
DisruptionController
StatefulSetController
CronJobController
CSRSigningController
CSRApprovingController
TTLController

預設啟動的可選控制器,可透過選項設定是否開啟
TokenController
NodeController
ServiceController
RouteController
PVBinderController
AttachDetachController

預設禁止的可選控制器,可透過選項設定是否開啟
BootstrapSignerController
TokenCleanerController

kube-controller-manager 啟動示例

kube-controller-manager \
  --enable-dynamic-provisioning=true \
  --feature-gates=AllAlpha=true \
  --horizontal-pod-autoscaler-sync-period=10s \
  --horizontal-pod-autoscaler-use-rest-clients=true \
  --node-monitor-grace-period=10s \
  --address=127.0.0.1 \
  --leader-elect=true \
  --kubeconfig=/etc/kubernetes/controller-manager.conf \
  --cluster-signing-key-file=/etc/kubernetes/pki/ca.key \
  --use-service-account-credentials=true \
  --controllers=*,bootstrapsigner,tokencleaner \
  --root-ca-file=/etc/kubernetes/pki/ca.crt \
  --service-account-private-key-file=/etc/kubernetes/pki/sa.key \
  --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt \
  --allocate-node-cidrs=true \
  --cluster-cidr=10.244.0.0/16 \
  --node-cidr-mask-size=24
  
  
# 注意:
Controller Manager 在啟動時,如果設定了--cluster-cidr 引數,對於沒有設定Sepc.PodCIDR的Node節點生成一個CIDR地址
並用該CIDR地址設定節點的Spec.PodCIDR屬性,防止不同的節點的CIDR地址發生衝突。

#高可用
在啟動時設定 --leader-elect=true 後,controller manager 會使用多節點選主的方式選擇主節點。
只有主節點才會呼叫 StartControllers() 啟動所有控制器,而其他從節點則僅執行選主演算法


#Node驅逐
預設情況下,Kubelet 每隔 10s (--node-status-update-frequency=10s) 更新 Node 的狀態,而 kube-controller-manager 每隔 5s 檢查一次 Node 的狀態 (--node-monitor-period=5s)。
kube-controller-manager 會在 Node 未更新狀態超過 40s 時 (--node-monitor-grace-period=40s),將其標記為 NotReady (Node Ready Condition: True on healthy, False on unhealthy and not accepting pods, Unknown on no heartbeat)。
當 Node 超過 5m 未更新狀態,則 kube-controller-manager 會驅逐該 Node 上的所有 Pod。

Kubernetes 會自動給 Pod 新增針對 node.kubernetes.io/not-ready 和 node.kubernetes.io/unreachable 的容忍度,且配置 tolerationSeconds=300。
你可以透過 tolerations 配置 Pod 的容忍度,來覆蓋預設的配置:
tolerations:
- key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 10
- key: "node.kubernetes.io/not-ready"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 10
  

Node 控制器在節點異常後,會按照預設的速率(--node-eviction-rate=0.1,即每10秒一個節點的速率)進行 Node 的驅逐。
Node 控制器按照 Zone 將節點劃分為不同的組,再跟進 Zone 的狀態進行速率調整:

Normal:所有節點都 Ready,預設速率驅逐。

PartialDisruption:即超過33% 的節點 NotReady 的狀態。
當異常節點比例大於 --unhealthy-zone-threshold=0.55 時開始減慢速率:
    - 小叢集(即節點數量小於 --large-cluster-size-threshold=50):停止驅逐
    - 大叢集,減慢速率為 --secondary-node-eviction-rate=0.01
FullDisruption:所有節點都 NotReady,返回使用預設速率驅逐。但當所有 Zone 都處在 FullDisruption 時,停止驅逐。

相關文章