關(guān)于 Kubernetes中kubelet的一些筆記
寫在前面
今天和小伙伴們分享K8s中Kubelet組件相關(guān)筆記
內(nèi)容涉及kubelet運(yùn)行機(jī)制解析包括
節(jié)點(diǎn)Kubelet服務(wù)管理
kubeletPod管理
Pod的健康檢查
食用需要有K8s基礎(chǔ),理解不足小伙伴幫忙指正
「 夜深難眠,是遺憾浪費(fèi)了昨天,是不想面對今天,還是希望時(shí)間停留在這些時(shí)刻,等一等迷茫的自己 --- 山河已無恙」
kubelet運(yùn)行機(jī)制淺析
在Kubernetes集群中,在每個(gè)Node (又稱Minion)上都會啟動一個(gè)kubelet服務(wù)進(jìn)程。該進(jìn)程用于處理Master下發(fā)到本節(jié)點(diǎn)的任務(wù)(調(diào)度器調(diào)度這個(gè)節(jié)點(diǎn)的pod),管理Pod及Pod中的容器。可以把kubelet 理解為在Ks集群中Node 節(jié)點(diǎn)的全權(quán)代理。
每個(gè)kubelet進(jìn)程都會在API Server(master節(jié)點(diǎn)的kube-apiserver服務(wù))上注冊節(jié)點(diǎn)自身的信息,定期向Master匯報(bào)節(jié)點(diǎn)資源的使用情況,并通過Metrics Server監(jiān)控容器和節(jié)點(diǎn)資源。
節(jié)點(diǎn)管理
Node通過設(shè)置kubelet的配置參數(shù)registerNode,來決定是否向master上的API Server服務(wù)注冊自己。如果該參數(shù)的值為true,那么kubelet將試著通過API Server注冊自己。默認(rèn)值為true,在kubelet啟動命令--config指定的配置文件中設(shè)定
Node節(jié)點(diǎn)的kubelet服務(wù)狀態(tài)
┌──[root@vms82.liruilongs.github.io]-[~]
└─$systemctl status kubelet.service
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
Drop-In: /usr/lib/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: active (running) since Sun 2022-06-12 14:58:48 CST; 1 months 1 days ago
Docs: https://kubernetes.io/docs/
Main PID: 970 (kubelet)
Memory: 194.4M
CGroup: /system.slice/kubelet.service
└─970 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/etc/kubernetes/kubelet.d --config=/var/lib/kubelet/config.yaml --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.5
從服務(wù)狀態(tài)可以看到,
當(dāng)前服務(wù)單元的描述信息:kubelet: The Kubernetes Node Agent 這是 一個(gè)Kubernetes 代理節(jié)點(diǎn)服務(wù)
當(dāng)前服務(wù)配置文件狀態(tài):loaded 已加載
當(dāng)前服務(wù)的插件配置文件位置:Drop-In: /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
kubelet服務(wù)的配置文件位置為: /usr/lib/systemd/system/kubelet.service,使用的是優(yōu)先級最低的配置文件,服務(wù)的配置文件的優(yōu)先級為:
本地配置: /etc/systemd/system/
運(yùn)行時(shí)配置: /run/systemd/system/
軟件包安裝的配置: /usr/lib/systemd/system/
當(dāng)前設(shè)置為開機(jī)自動啟動,enabled;
軟件廠商默認(rèn)為不開機(jī)自啟:vendor preset: disabled
服務(wù)當(dāng)前正在運(yùn)行,運(yùn)行開始時(shí)間;時(shí)常:Active: active (running) since Sun 2022-06-12 14:58:48 CST; 1 months 1 days ago
幫助文檔位置:Docs: https://kubernetes.io/docs/
進(jìn)程PID:Main PID: 970 (kubelet)
消耗內(nèi)存:Memory: 194.4M
Cgroup相關(guān)用的什么slice。對應(yīng)的Cgroup分組:CGroup: /system.slice/kubelet.service
通過Cgroup,我們可以監(jiān)聽任務(wù)數(shù)、CPU、內(nèi)存和 IO變化
┌──[root@vms82.liruilongs.github.io]-[~]
└─$watch -n 3 -d 'systemd-cgtop | grep /system.slice/kubelet.service'
Every 3.0s: systemd-cgtop | grep /system.slice/kubelet.service Thu Jul 14 23:53:40 2022
/system.slice/kubelet.service
1 - 194.7M - -
在上面的Service中,除了單元文件 kubelet.service之外,還有一個(gè)Drop-In目錄 /usr/lib/systemd/system/kubelet.service.d。這個(gè)目錄中所有后綴為".conf"的文件將在單元文件本身被解析之后被解析,所以說kubelet.service 單元文件的值可能會被覆蓋。
通過systemctl cat kubelet.service 可以查看所有的Service單元相關(guān)文件
┌──[root@vms82.liruilongs.github.io]-[/usr/lib/systemd/system/kubelet.service.d]
└─$systemctl cat kubelet.service
# /usr/lib/systemd/system/kubelet.service
[Unit]
Description=kubelet: The Kubernetes Node Agent #描述信息
Documentation=https://kubernetes.io/docs/ #幫助文檔
Wants=network-online.target # 強(qiáng)依賴
After=network-online.target #依賴關(guān)系,在network-online.target之后執(zhí)行
[Service]
ExecStart=/usr/bin/kubelet # 啟動命令
Restart=always #重啟策略:無條件的重啟
StartLimitInterval=0 #設(shè)置單元的啟動頻率限制,沒有限制
RestartSec=10 # 10秒后重啟
[Install]
WantedBy=multi-user.target #屬于那個(gè)target
# /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/etc/kubernetes/kube
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS
這里的Target單元:即用于模擬實(shí)現(xiàn)“運(yùn)行級別”,文件擴(kuò)展名為.target,可以理解Target 就是一個(gè) Unit組,包含許多相關(guān)的單元,可以是Service,Socket,Device 等,
在紅帽的Linux發(fā)行版中,CentOS7之后,采用加載target的方式來替代之前的啟動級別。有兩個(gè)常見的target:multi-user.target與graphical.target。它們分別表示之前運(yùn)行級別中的3(字符模式+NFS)與5(圖像模式)級別。
列出當(dāng)前使用的運(yùn)行級別
┌──[root@vms82.liruilongs.github.io]-[/etc/kubernetes/manifests]
└─$systemctl get-default
multi-user.target
在較新版本中,kubelet棄用了大部分的啟動參數(shù),保留了較小的部分,大部分的啟動參數(shù)通--config啟動參數(shù)所給的配置文件中進(jìn)行設(shè)置,也就是配置參數(shù)
/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf 為進(jìn)程啟動時(shí)最后的啟動命令,具體的啟動參數(shù)說明
/usr/bin/kubelet \
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \ #某 kubeconfig 文件的路徑,該文件將用于獲取 kubelet 的客戶端證書。 如果 --kubeconfig 所指定的文件不存在,則使用引導(dǎo)所用 kubeconfig 從 API 服務(wù)器請求客戶端證書。成功后,將引用生成的客戶端證書和密鑰的 kubeconfig 寫入 --kubeconfig 所指定的路徑??蛻舳俗C書和密鑰文件將存儲在 --cert-dir 所指的目錄。
--kubeconfig=/etc/kubernetes/kubelet.conf \ #kubeconfig 配置文件的路徑,指定如何連接到 API 服務(wù)器。 提供 --kubeconfig 將啟用 API 服務(wù)器模式,而省略 --kubeconfig 將啟用獨(dú)立模式。
--pod-manifest-path=/etc/kubernetes/kubelet.d \ #設(shè)置包含要運(yùn)行的靜態(tài) Pod 的文件的路徑,或單個(gè)靜態(tài) Pod 文件的路徑。已棄用
--config=/var/lib/kubelet/config.yaml \ #kubelet配置文件位置
--network-plugin=cni \ #設(shè)置 kubelet/Pod 生命周期中各種事件調(diào)用的網(wǎng)絡(luò)插件的名稱,將會隨著 dockershim 一起刪除,已棄用
--pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.5 #所指定的鏡像不會被鏡像垃圾收集器刪除。 當(dāng)容器運(yùn)行環(huán)境設(shè)置為 docker 時(shí),各個(gè) Pod 中的所有容器都會 使用此鏡像中的網(wǎng)絡(luò)和 IPC 名字空間。 其他 CRI 實(shí)現(xiàn)有自己的配置來設(shè)置此鏡像。
systemctl show kubelet.service 可用于查看所有的參數(shù)
┌──[root@vms82.liruilongs.github.io]-[/etc/kubernetes/manifests]
└─$systemctl show kubelet.service
Type=simple
Restart=always
NotifyAccess=none
RestartUSec=10s
TimeoutStartUSec=1min 30s
TimeoutStopUSec=1min 30s
WatchdogUSec=0
WatchdogTimestamp=日 2022-06-12 14:58:48 CST
WatchdogTimestampMonotonic=21325336
StartLimitInterval=0
StartLimitBurst=5
StartLimitAction=none
FailureAction=none
......
查看kubelet.service 的正向依賴,所謂正向依賴,是在kubelet之前啟動的單元
┌──[root@vms82.liruilongs.github.io]-[~]
└─$systemctl list-dependencies kubelet.service
kubelet.service
● ├─system.slice
● ├─basic.target
● │ ├─microcode.service
● │ ├─rhel-autorelabel-mark.service
● │ ├─rhel-autorelabel.service
● │ ├─rhel-configure.service
● │ ├─rhel-dmesg.service
● │ ├─rhel-loadmodules.service
● │ ├─selinux-policy-migrate-local-changes@targeted.service
● │ ├─paths.target
● │ ├─slices.target
● │ │ ├─-.slice
● │ │ └─system.slice
● │ ├─sockets.target
● │ │ ├─dbus.socket
● │ │ ├─rpcbind.socket
● │ │ ├─systemd-initctl.socket
● │ │ ├─systemd-journald.socket
● │ │ ├─systemd-shutdownd.socket
● │ │ ├─systemd-udevd-control.socket
● │ │ └─systemd-udevd-kernel.socket
● │ ├─sysinit.target
● │ │ ├─dev-hugepages.mount
● │ │ ├─dev-mqueue.mount
● │ │ ├─kmod-static-nodes.service
● │ │ ├─plymouth-read-write.service
● │ │ ├─plymouth-start.service
● │ │ ├─proc-sys-fs-binfmt_misc.automount
● │ │ ├─sys-fs-fuse-connections.mount
● │ │ ├─sys-kernel-config.mount
● │ │ ├─sys-kernel-debug.mount
● │ │ ├─systemd-ask-password-console.path
● │ │ ├─systemd-binfmt.service
● │ │ ├─systemd-firstboot.service
● │ │ ├─systemd-hwdb-update.service
● │ │ ├─systemd-journal-catalog-update.service
● │ │ ├─systemd-journal-flush.service
● │ │ ├─systemd-journald.service
● │ │ ├─systemd-machine-id-commit.service
● │ │ ├─systemd-modules-load.service
● │ │ ├─systemd-random-seed.service
● │ │ ├─systemd-sysctl.service
● │ │ ├─systemd-tmpfiles-setup-dev.service
● │ │ ├─systemd-tmpfiles-setup.service
● │ │ ├─systemd-udev-trigger.service
● │ │ ├─systemd-udevd.service
● │ │ ├─systemd-update-done.service
● │ │ ├─systemd-update-utmp.service
● │ │ ├─systemd-vconsole-setup.service
● │ │ ├─cryptsetup.target
● │ │ ├─local-fs.target
● │ │ │ ├─-.mount
● │ │ │ ├─rhel-import-state.service
● │ │ │ ├─rhel-readonly.service
● │ │ │ └─systemd-remount-fs.service
● │ │ └─swap.target
● │ └─timers.target
● │ └─systemd-tmpfiles-clean.timer
● └─network-online.target
● └─NetworkManager-wait-online.service
查看kubelet.service的反向依賴,在kubelet之后啟動的單元
┌──[root@vms82.liruilongs.github.io]-[~]
└─$systemctl list-dependencies kubelet.service --reverse
kubelet.service
● └─multi-user.target # 字符級別
● └─graphical.target # 圖形級別
┌──[root@vms82.liruilongs.github.io]-[~]
└─$systemctl list-dependencies graphical.target | grep kube
● ├─kubelet.service
--kubeconfig=/etc/kubernetes/kubelet.conf 認(rèn)證文件,使用 kubelet.conf 文件來組織有關(guān)集群、用戶、命名空間和身份認(rèn)證機(jī)制的信息。kubectl 命令行工具使用 kubeconfig 文件來查找選擇集群所需的信息,并與集群的 API 服務(wù)器進(jìn)行通信。
┌──[root@vms82.liruilongs.github.io]-[/etc/kubernetes/manifests]
└─$cat /etc/kubernetes/kubelet.conf
apiVersion: v1
clusters: #集群信息:
- cluster: #集群CA證書
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1USXhNakUyTURBME1sb1hEVE14TVRJeE1ERTJNREEwTWxvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTkdkCisrWnhFRDJRQlR2Rm5ycDRLNFBrd2lsYXUrNjdXNTVobVdwc09KSHF6ckVoWUREY3l4ZTU2Z1VJVDFCUTFwbU0KcGFrM0V4L0JZRStPeHY4ZmxtellGbzRObDZXQjl4VXovTW5HQi96dHZsTGpaVEVHZy9SVlNIZTJweCs2MUlSMQo2Mkh2OEpJbkNDUFhXN0pmR3VXNDdKTXFUNTUrZUNuR00vMCtGdnI2QUJnT2YwNjBSSFFuaVlzeGtpSVJmcjExClVmcnlPK0RFTGJmWjFWeDhnbi9tcGZEZ044cFgrVk9FNFdHSDVLejMyNDJtWGJnL3A0emd3N2NSalpSWUtnVlUKK2VNeVIyK3pwaTBhWW95L2hLYmg4RGRUZ3FZeERDMzR6NHFoQ3RGQnVia1hmb3Ftc3FGNXpQUm1ZS051RUgzVAo2c1FNSFl4emZXRkZvSGQ2Y0JNQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZHRGNLU3V1VjVNNXlaTkJHUDEvNmg3TFk3K2VNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRVE0SUJhM0hBTFB4OUVGWnoyZQpoSXZkcmw1U0xlanppMzkraTdheC8xb01SUGZacElwTzZ2dWlVdHExVTQ2V0RscTd4TlFhbVVQSFJSY1RrZHZhCkxkUzM5Y1UrVzk5K3lDdXdqL1ZrdzdZUkpIY0p1WCtxT1NTcGVzb3lrOU16NmZxNytJUU9lcVRTbGpWWDJDS2sKUFZxd3FVUFNNbHFNOURMa0JmNzZXYVlyWUxCc01EdzNRZ3N1VTdMWmg5bE5TYVduSzFoR0JKTnRndjAxdS9MWAo0TnhKY3pFbzBOZGF1OEJSdUlMZHR1dTFDdEFhT21CQ2ZjeTBoZHkzVTdnQXh5blR6YU1zSFFTamIza0JDMkY5CkpWSnJNN1FULytoMStsOFhJQ3ZLVzlNM1FlR0diYm13Z1lLYnMvekswWmc1TE5sLzFJVThaTUpPREhTVVBlckQKU09ZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://192.168.26.81:6443 #集群地址
name: default-cluster
contexts: #上下文信息
- context: #所有上下文信息
cluster: default-cluster
namespace: default
user: default-auth
name: default-context
current-context: default-context #當(dāng)前上下文
kind: Config
preferences: {}
users: #用戶信息
- name: default-auth
user: #用戶CA證書
client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
client-key: /var/lib/kubelet/pki/kubelet-client-current.pem #用戶私鑰
關(guān)于認(rèn)證文件的生成小伙伴們可以看看我之前的文章。
關(guān)于Kubernetes中API Server使用token、kubeconfig文件認(rèn)證的一些筆記 https://liruilong.blog.csdn.net/article/details/122694838
--config=/var/lib/kubelet/config.yaml 啟動參數(shù)配置文件
┌──[root@vms82.liruilongs.github.io]-[~]
└─$cat /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 0s
cacheUnauthorizedTTL: 0s
cgroupDriver: systemd #cgroupDriver是 kubelet 用來操控宿主系統(tǒng)上控制組(CGroup) 的驅(qū)動程序(cgroupfs 或 systemd)。默認(rèn)值:"cgroupfs"
clusterDNS: #clusterDNS是集群 DNS 服務(wù)器的 IP 地址的列表。 如果設(shè)置了,kubelet 將會配置所有容器使用這里的 IP 地址而不是宿主系統(tǒng)上的 DNS 服務(wù)器來完成 DNS 解析。
- 10.96.0.10
clusterDomain: cluster.local #clusterDomain是集群的 DNS 域名。
cpuManagerReconcilePeriod: 0s #cpuManagerReconcilePeriod是 CPU 管理器的協(xié)調(diào)周期時(shí)長
evictionPressureTransitionPeriod: 0s #evictionPressureTransitionPeriod設(shè)置 kubelet 離開驅(qū)逐壓力狀況之前必須要等待的時(shí)長。
fileCheckFrequency: 0s
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 0s
imageMinimumGCAge: 0s
kind: KubeletConfiguration
logging: {}
memorySwap: {}
nodeStatusReportFrequency: 0s
nodeStatusUpdateFrequency: 0s
rotateCertificates: true
runtimeRequestTimeout: 0s
shutdownGracePeriod: 0s
shutdownGracePeriodCriticalPods: 0s
staticPodPath: /etc/kubernetes/manifests #staticPodPath 是指向要運(yùn)行的本地(靜態(tài))Pod 的目錄
streamingConnectionIdleTimeout: 0s #streamingConnectionIdleTimeout設(shè)置流式連接在被自動關(guān)閉之前可以空閑的最長時(shí)間。
syncFrequency: 0s #syncFrequency 是對運(yùn)行中的容器和配置進(jìn)行同步的最長周期。
volumeStatsAggPeriod: 0s #volumeStatsAggPeriod是計(jì)算和緩存所有 Pod 磁盤用量的頻率。
參數(shù)這些官網(wǎng)都有詳細(xì)的介紹,小伙伴遇到需要查詢可以移步官網(wǎng)
查看配置文件參數(shù):https://kubernetes.io/zh-cn/docs/reference/config-api/kubelet-config.v1beta1/
查看啟動參數(shù):https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kubelet/
如果在集群運(yùn)行過程中遇到集群資源不足的情況,可以通過添加機(jī)器及運(yùn)用kubelet的自注冊模式來實(shí)現(xiàn)擴(kuò)容。在某些情況下,Kubernetes集群中的某些kubelet沒有選擇自注冊模式,用戶需要自己去配置Node的資源信息,同時(shí)告知Node上Kubelet API Server的位置。一般情況下,如果有成熟的安裝工具,比如kubeadm等,還是使用工具方便一點(diǎn)。
集群管理者能夠創(chuàng)建和修改節(jié)點(diǎn)信息。如果管理者希望手動創(chuàng)建節(jié)點(diǎn)信息,則通過設(shè)置kubelet的配置參數(shù)“registerNode”即可完成。
kubelet在啟動時(shí)通過API Server注冊節(jié)點(diǎn)信息,并定時(shí)向API Server發(fā)送節(jié)點(diǎn)的新消息,API Server在接收到這些信息后,將這些信息寫入etcd。
通過kubelet的配置參數(shù) nodeStatusUpdateFrequency 用于設(shè)置kubelet每隔多長時(shí)間向API Server報(bào)告節(jié)點(diǎn)狀態(tài),默認(rèn)為10s。注意:更改此常量時(shí)請務(wù)必謹(jǐn)慎, 它必須與節(jié)點(diǎn)控制器中的nodeMonitorGracePeriod一起使用。
通過journalctl -u kubelet.service 查看日志,有的時(shí)候,kubelet服務(wù)可能死掉,通過journalctl來排除問題
┌──[root@vms82.liruilongs.github.io]-[~]
└─$ journalctl -u kubelet.service
-- Logs begin at 日 2022-06-12 14:58:36 CST, end at 四 2022-07-14 22:16:38 CST. --
6月 12 14:58:48 vms82.liruilongs.github.io systemd[1]: Started kubelet: The Kubernetes Node Agent.
6月 12 14:58:48 vms82.liruilongs.github.io systemd[1]: Starting kubelet: The Kubernetes Node Agent...
6月 12 14:58:49 vms82.liruilongs.github.io kubelet[970]: Flag --pod-manifest-path has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
6月 12 14:58:49 vms82.liruilongs.github.io kubelet[970]: Flag --network-plugin has been deprecated, will be removed along with dockershim.
6月 12 14:58:49 vms82.liruilongs.github.io kubelet[970]: Flag --pod-manifest-path has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
6月 12 14:58:49 vms82.liruilongs.github.io kubelet[970]: Flag --network-plugin has been deprecated, will be removed along with dockershim.
6月 12 14:58:49 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:49.396358 970 server.go:440] "Kubelet version" kubeletVersion="v1.22.2"
6月 12 14:58:49 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:49.397298 970 server.go:868] "Client rotation is on, will bootstrap in background"
6月 12 14:58:49 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:49.409027 970 certificate_store.go:130] Loading cert/key pair from "/var/lib/kubelet/pki/kubelet-client-current.pem".
6月 12 14:58:49 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:49.422834 970 dynamic_cafile_content.go:155] "Starting controller" name="client-ca-bundle::/etc/kubernetes/pki/ca.crt"
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.834139 970 server.go:687] "--cgroups-per-qos enabled, but --cgroup-root was not specified. defaulting to /"
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.836548 970 container_manager_linux.go:280] "Container manager verified user specified cgroup-root exists" cgroupRoot=[]
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.836913 970 container_manager_linux.go:285] "Creating Container Manager object based on Node Config" nodeConfig={RuntimeCgroupsName: SystemCgroupsName: KubeletCgroupsName: ContainerRuntime:docker CgroupsPerQOS:true CgroupRoot:/ CgroupDriver:systemd KubeletRootDir:/var/lib/kubelet ProtectKernelDefaults:false NodeAllocatableConfig:{KubeReservedCgroupName: SystemReservedCgroupName: ReservedSystemCPUs: EnforceNodeAllocatable:map[pods:{}] KubeReserved:map[] SystemReserved:map[] HardEvictionThresholds:[{Signal:imagefs.available Operator:LessThan Value:{Quantity:<nil> Percentage:0.15} GracePeriod:0s MinReclaim:<nil>} {Signal:memory.available Operator:LessThan Value:{Quantity:100Mi Percentage:0} GracePeriod:0s MinReclaim:<nil>} {Signal:nodefs.available Operator:LessThan Value:{Quantity:<nil> Percentage:0.1} GracePeriod:0s MinReclaim:<nil>} {Signal:nodefs.inodesFree Operator:LessThan Value:{Quantity:<nil> Percentage:0.05} GracePeriod:0s MinReclaim:<nil>}]} QOSReserved:map[] ExperimentalCPUManagerPolicy:none ExperimentalCPUManagerPolicyOptions:map[] ExperimentalTopologyManagerScope:container ExperimentalCPUManagerReconcilePeriod:10s ExperimentalMemoryManagerPolicy:None ExperimentalMemoryManagerReservedMemory:[] ExperimentalPodPidsLimit:-1 EnforceCPULimits:true CPUCFSQuotaPeriod:100ms ExperimentalTopologyManagerPolicy:none}
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.838174 970 topology_manager.go:133] "Creating topology manager with policy per scope" topologyPolicyName="none" topologyScopeName="container"
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.838223 970 container_manager_linux.go:320] "Creating device plugin manager" devicePluginEnabled=true
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.838441 970 state_mem.go:36] "Initialized new in-memory state store"
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.839147 970 kubelet.go:314] "Using dockershim is deprecated, please consider using a full-fledged CRI implementation"
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.840462 970 client.go:78] "Connecting to docker on the dockerEndpoint" endpoint="unix:///var/run/docker.sock"
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.840495 970 client.go:97] "Start docker client with request timeout" timeout="2m0s"
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.851651 970 docker_service.go:566] "Hairpin mode is set but kubenet is not enabled, falling back to HairpinVeth" hairpinMode=promiscuous-bridge
6月 12 14:58:50 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:50.852141 970 docker_service.go:242] "Hairpin mode is set" hairpinMode=hairpin-veth
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:51.041739 970 docker_service.go:257] "Docker cri networking managed by the network plugin" networkPluginName="cni"
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:51.056895 970 docker_service.go:264] "Docker Info" dockerInfo=&{ID:IBJD:6MIX:4FUA:Z6W3:UIL2:VGXR:K7PS:PN3X:BVBO:5MKQ:D3WY:6JJY Containers:37 ContainersRunning:0 ContainersPaused:0 ContainersStopped:37 Images:56 Driver:overlay2 DriverStatus:[[Backing Filesystem xfs] [Supports d_type true] [Native Overlay Diff true] [userxattr false]] SystemStatus:[] Plugins:{Volume:[local] Network:[bridge host ipvlan macvlan null overlay] Authorization:[] Log:[awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog]} MemoryLimit:true SwapLimit:true KernelMemory:true KernelMemoryTCP:true CPUCfsPeriod:true CPUCfsQuota:true CPUShares:true CPUSet:true PidsLimit:true IPv4Forwarding:true BridgeNfIptables:true BridgeNfIP6tables:true Debug:false NFd:26 OomKillDisable:true NGoroutines:37 SystemTime:2022-06-12T14:58:51.042314205+08:00 LoggingDriver:json-file CgroupDriver:systemd CgroupVersion:1 NEventsListener:0 KernelVersion:3.10.0-693.el7.x86_64 OperatingSystem:CentOS Linux 7 (Core) OSVersion:7 OSType:linux Architecture:x86_64 IndexServerAddress:https://index.docker.io/v1/ RegistryConfig:0xc0007a4230 NCPU:3 MemTotal:5104164864 GenericResources:[] DockerRootDir:/var/lib/docker HTTPProxy: HTTPSProxy: NoProxy: Name:vms82.liruilongs.github.io Labels:[] ExperimentalBuild:false ServerVersion:20.10.9 ClusterStore: ClusterAdvertise: Runtimes:map[io.containerd.runc.v2:{Path:runc Args:[] Shim:<nil>} io.containerd.runtime.v1.linux:{Path:runc Args:[] Shim:<nil>} runc:{Path:runc Args:[] Shim:<nil>}] DefaultRuntime:runc Swarm:{NodeID: NodeAddr: LocalNodeState:inactive ControlAvailable:false Error: RemoteManagers:[] Nodes:0 Managers:0 Cluster:<nil> Warnings:[]} LiveRestoreEnabled:false Isolation: InitBinary:docker-init ContainerdCommit:{ID:5b46e404f6b9f661a205e28d59c982d3634148f8 Expected:5b46e404f6b9f661a205e28d59c982d3634148f8} RuncCommit:{ID:v1.0.2-0-g52b36a2 Expected:v1.0.2-0-g52b36a2} InitCommit:{ID:de40ad0 Expected:de40ad0} SecurityOptions:[name=seccomp,profile=default] ProductLicense: DefaultAddressPools:[]
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: Warnings:[]}
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:51.056930 970 docker_service.go:277] "Setting cgroupDriver" cgroupDriver="systemd"
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:51.098194 970 kubelet.go:418] "Attempting to sync node with API server"
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:51.098254 970 kubelet.go:279] "Adding static pod path" path="/etc/kubernetes/kubelet.d"
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:51.098886 970 kubelet.go:290] "Adding apiserver pod source"
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:51.099026 970 apiserver.go:42] "Waiting for node sync before watching apiserver pods"
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:51.113064 970 kuberuntime_manager.go:244] "Container runtime initialized" containerRuntime="docker" version="20.10.9" apiVersion="1.41.0"
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:51.117575 970 server.go:1213] "Started kubelet"
6月 12 14:58:51 vms82.liruilongs.github.io kubelet[970]: I0612 14:58:51.118010 970 server.go:149] "Starting to listen" address="0.0.0.0" port=10250
Pod管理
kubelet 根據(jù) PodSpec 工作。PodSpec 是描述 pod 的 YAML 或 JSON 對象。kubelet 采用一組通過各種機(jī)制(主要通過 apiserver)提供的 PodSpec,并確保這些 PodSpec 中描述的容器運(yùn)行且健康。kubelet 不會管理不是由 Kubernetes 創(chuàng)建的容器。
kubelet通過以下幾種方式獲取自身Node上要運(yùn)行的Pod清單。
文件:kubelet啟動參數(shù) --config 指定的配置文件目錄下的文件(默認(rèn)目錄為“/etc/kubernetes/manifests/”)。通過fileCheckFrequency設(shè)置檢查該文件目錄的時(shí)間間隔,默認(rèn)為20s。
HTTP端點(diǎn)(URL):通過“-manifest-url”參數(shù)設(shè)置。通過--http-check-frequency設(shè)置檢查該HTTP端點(diǎn)數(shù)據(jù)的時(shí)間間隔,默認(rèn)為20s。
API Server:kubelet通過API Server監(jiān)聽etcd目錄,同步Pod列表。
所有以非API Server方式創(chuàng)建的Pod都叫作Static Pod。kubelet將Static Pod的狀態(tài)匯報(bào)給API Server,API Server為該Static Pod創(chuàng)建一個(gè)Mirror Pod和其相匹配。Mirror Pod的狀態(tài)將真實(shí)反映Static Pod的狀態(tài)。
當(dāng)Static Pod被刪除時(shí),與之相對應(yīng)的Mirror Pod也會被刪除。
kubelet通過API Server Client使用Watch加List的方式監(jiān)聽“/registry/nodes/$”當(dāng)前節(jié)點(diǎn)的名稱和“registry/pods”目錄,將獲取的信息同步到本地緩存中。kubelet監(jiān)聽etcd,所有針對Pod的操作都會被kubelet監(jiān)聽。如果發(fā)現(xiàn)有新的綁定到本節(jié)點(diǎn)的Pod,則按照Pod清單的要求創(chuàng)建該P(yáng)od。
發(fā)現(xiàn)本地的Pod被修改,則kubelet會做出相應(yīng)的修改,比如在刪除Pod中的某個(gè)容器時(shí),會通過Docker Client刪除該容器。
發(fā)現(xiàn)刪除本節(jié)點(diǎn)的Pod,則刪除相應(yīng)的Pod,并通過Docker Client刪除Pod中的容器。
kubelet讀取監(jiān)聽到的信息,如果是創(chuàng)建和修改Pod任務(wù),則做如下處理。
為該P(yáng)od創(chuàng)建一個(gè)數(shù)據(jù)目錄。
從API Server讀取該P(yáng)od清單。
為該P(yáng)od掛載外部卷(External Volume)。
下載Pod用到的Secret。
檢查已經(jīng)運(yùn)行在節(jié)點(diǎn)上的Pod,如果該P(yáng)od沒有容器或Pause容器(“kubernetes/pause”鏡像創(chuàng)建的容器)沒有啟動,則先停止Pod里所有容器的進(jìn)程。如果在Pod中有需要刪除的容器,則刪除這些容器。
用kubernetes/pause鏡像為每個(gè)Pod都創(chuàng)建一個(gè)容器。該P(yáng)ause容器用于接管Pod中所有其他容器的網(wǎng)絡(luò)。每創(chuàng)建一個(gè)新的Pod,kubelet都會先創(chuàng)建一個(gè)Pause容器,然后創(chuàng)建其他容器?!発ubernetes/pause”鏡像大概有200KB,是個(gè)非常小的容器鏡像。
為Pod中的每個(gè)容器做如下處理。
為容器計(jì)算一個(gè)Hash值,然后用容器的名稱去查詢對應(yīng)Docker容器的Hash值。若查找到容器,且二者的Hash值不同,則停止Docker中容器的進(jìn)程,并停止與之關(guān)聯(lián)的Pause容器的進(jìn)程;若二者相同,則不做任何處理。
如果容器被終止了,且容器沒有指定的restartPolicy(重啟策略),則不做任何處理。
調(diào)用Docker Client下載容器鏡像,調(diào)用Docker Client運(yùn)行容器。
容器健康檢查
Pod通過兩類探針來檢查容器的健康狀態(tài)。
LivenessProbe探針(存活)
一類是LivenessProbe探針,用于判斷容器是否健康并反饋給kubelet。如果LivenessProbe探針探測到容器不健康,則kubelet將刪除該容器,并根據(jù)容器的重啟策略做相應(yīng)的處理。如果一個(gè)容器不包含LivenessProbe探針,那么kubelet認(rèn)為該容器的LivenessProbe探針返回的值永遠(yuǎn)是Success;
一個(gè) ReadinessProbe探針Demo,在容器內(nèi)部執(zhí)行一個(gè)命令,如果該命令的返回碼為0,則表明容器健康。
┌──[root@vms81.liruilongs.github.io]-[~/ansible/liveness-probe]
└─$cat liveness-probe.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod-liveness
name: pod-liveness
spec:
containers:
- args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; slee 10
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5 #容器啟動的5s內(nèi)不監(jiān)測
periodSeconds: 5 #每5s鐘檢測一次
image: busybox
imagePullPolicy: IfNotPresent
name: pod-liveness
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
ReadinessProbe探針(服務(wù)可用)
另一類是ReadinessProbe探針,用于判斷容器是否啟動完成,且準(zhǔn)備接收請求。如果ReadinessProbe探針檢測到容器啟動失敗,則Pod的狀態(tài)將被修改,Endpoint Controller將從Service的Endpoint中刪除包含該容器所在Pod的IP地址的Endpoint條目。
kubelet定期調(diào)用容器中的LivenessProbe探針來診斷容器的健康狀況。LivenessProbe包含以下3種實(shí)現(xiàn)方式。
ExecAction:在容器內(nèi)部執(zhí)行一個(gè)命令,如果該命令的退出狀態(tài)碼為0,則表明容器健康。
TCPSocketAction:通過容器的IP地址和端口號執(zhí)行TCP檢查,如果端口能被訪問,則表明容器健康。
HTTPGetAction:通過容器的IP地址和端口號及路徑調(diào)用HTTP Get方法,如果響應(yīng)的狀態(tài)碼大于等于200且小于等于400,則認(rèn)為容器狀態(tài)健康。
一個(gè) ReadinessProbe探針Demo,
┌──[root@vms81.liruilongs.github.io]-[~/ansible/liveness-probe]
└─$cat liveness-probe-tcp.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod-livenss-probe
name: pod-livenss-probe
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod-livenss-probe
livenessProbe:
failureThreshold: 3
tcpSocket:
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
關(guān)于更多小伙伴們可以看看我之前的博文關(guān)于
Kubernetes中Pod健康檢測和服務(wù)可用性檢查的一些筆記 https://blog.csdn.net/sanhewuyang/article/details/122020019
資源監(jiān)控
在新的Kubernetes監(jiān)控體系中,Metrics Server用于提供Core Metrics(核心指標(biāo)),包括Node和Pod的CPU和內(nèi)存使用數(shù)據(jù)。其他Custom Metrics(自定義指標(biāo))則由第三方組件(如Prometheus)采集和存儲。這里感興趣的小伙伴可以看看我之前的博文
關(guān)于 Kubernetes集群性能監(jiān)控(kube-prometheus-stack/Metrics Server)的一些筆記 https://liruilong.blog.csdn.net/article/details/122729697
博客內(nèi)容整理參考
https://kubernetes.io/zh-cn/docs/
https://www.cnblogs.com/wangqingyong/p/14542937.html
https://www.freedesktop.org/software/systemd/man/systemd.unit.html
http://www.jinbuguo.com/systemd/systemd.service.html
《Kubernetes權(quán)威指南》 第四版
作者:山河已無恙
歡迎關(guān)注微信公眾號 :山河已無恙