Kubernetes集群升級與etcd備份恢復指南

目錄

Kubernetes etcd備份恢復

集群管理命令

環境變量

查看etcd版本

查看etcd集群節點信息

查看集群健康狀態

查看告警事件

添加成員(單節點部署的etcd無法直接擴容)(不用做)

更新成員

刪除成員

數據庫操作命令

增加(put)

查詢(get)

刪除(del)

更新(put覆蓋)

查詢鍵歷史記錄查詢

監聽命令

監聽單個鍵

同時監聽多個鍵

租約命令

添加租約

查看租約

租約續約

刪除租約

多key同一租約

備份恢復命令

生成快照

查看快照

恢復快照

備份恢復演示

恢復案例

單master集群

多master集群

Kubernetes集群升級指南

前言

一、集群升級過程輔助命令

二、升級master節點

2.1、升級kubeadm。

2.2、驗證升級計劃

2.3、master節點升級

三、升級node節點

總結


Kubernetes etcd備份恢復

集群管理命令

etcdctl是一個命令行的客戶端,它提供了一些命令,可以方便我們在對服務進行測試或者手動修改數據庫內容。etcdctl命令基本用法如下所示:

etcdctl [global options] command [command options] [args...]

具體的命令選項參數可以通過 etcdctl command --help來獲取相關幫助

環境變量

獲得etcd數據庫的訪問url

[root@k8s-master ~]# kubectl -n kube-system get pods etcd-k8s-master -o yaml  | grep -A10 "containers:" | grep "https://"- --advertise-client-urls=https://192.168.158.15:2379- --initial-advertise-peer-urls=https://192.168.158.15:2380- --initial-cluster=k8s-master=https://192.168.158.15:2380

如果遇到使用了TLS加密的集群,通常每條指令都需要指定證書路徑和etcd節點地址,可以把相關命令行參數添加在環境變量中,在~/.bashrc添加以下內容:

[root@tiaoban etcd]# cat ~/.bashrc
HOST_1=https://192.168.166.3:2379
ENDPOINTS=${HOST_1}
# 如果需要使用原生命令,在命令開頭加一個\ 例如:\etcdctl command
alias etcdctl="etcdctl --cert /etc/kubernetes/pki/etcd/peer.crt --key /etc/kubernetes/pki/etcd/peer.key --endpoints=https://192.168.158.6:2379  --insecure-skip-tls-verify"
[root@tiaoban etcd]# source ~/.bashrc
查看etcd版本
[root@tiaoban etcd]# etcdctl version
etcdctl version: 3.4.23
API version: 3.4
查看etcd集群節點信息
etcdctl  member list -w table
+------------------+---------+------------+----------------------------+----------------------------+------------+
| ? ? ?  ID ? ? ?  | STATUS  | ?  NAME ?  | ? ? ? ? PEER ADDRS ? ? ? ? | ? ? ?  CLIENT ADDRS ? ? ?  | IS LEARNER |
+------------------+---------+------------+----------------------------+----------------------------+------------+
| eba84a8571780cea | started | k8s-master | https://192.168.166.3:2380 | https://192.168.166.3:2379 | ? ? ?false |
+------------------+---------+------------+----------------------------+----------------------------+------------+
查看集群健康狀態
etcdctl endpoint status -w table
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ? ? ? ?  ENDPOINT ? ? ? ?  | ? ? ?  ID ? ? ?  | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| https://192.168.166.3:2379 | eba84a8571780cea | ?3.5.15 | ?7.1 MB | ? ? ?true | ? ? ?false | ? ? ? ? 4 | ? ? ?15658 | ? ? ? ? ? ? ?15658 | ? ? ?  |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
?
####表格內容解析
?ENDPOINT:節點的地址,這里是 https://192.168.158.6:2379。這表示該節點的網絡地址和端口。ID:節點的唯一標識符,這里是 6dc5c9ae772d8898。VERSION:節點的版本號,這里是 3.5.9。DB SIZE:數據庫大小,這里是 9.1 MB。IS LEADER:是否為集群的領導者節點。true 表示該節點是領導者。IS LEARNER:是否為學習者節點。false 表示該節點不是學習者節點。RAFT TERM:Raft協議中的任期編號,這里是 4。Raft協議用于分布式系統的共識機制,任期編號用于區分不同的選舉周期。RAFT INDEX:Raft協議中的日志索引,這里是 30622。它表示當前日志的最新位置。RAFT APPLIED INDEX:Raft協議中已應用的日志索引,這里是 30622。它表示已提交并應用到狀態機的日志位置。ERRORS:錯誤信息,這里為空,表示沒有錯誤
查看告警事件

如果內部出現問題,會觸發告警,可以通過命令查看告警引起原因,命令如下所示:

etcdctl alarm <subcommand> [flags]

常用的子命令主要有兩個:

# 查看所有告警
etcdctl alarm list
# 解除所有告警
etcdctl alarm disarm
添加成員(單節點部署的etcd無法直接擴容)(不用做)

當集群部署完成后,后續可能需要進行節點擴縮容,就可以使用member命令管理節點。先查看當前集群信息

[root@tiaoban etcd]# etcdctl endpoint status --cluster -w table
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ? ? ? ?  ENDPOINT ? ? ? ?  | ? ? ?  ID ? ? ?  | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://192.168.10.100:2379 | 2e0eda3ad6bc6e1e | ?3.4.23 | ? 20 kB | ? ? ?true | ? ? ?false | ? ? ? ? 8 | ? ? ? ? 16 | ? ? ? ? ? ? ? ? 16 | ? ? ?  |
|  http://192.168.10.12:2379 | 5d2c1bd3b22f796f | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 8 | ? ? ? ? 16 | ? ? ? ? ? ? ? ? 16 | ? ? ?  |
|  http://192.168.10.11:2379 | bc34c6bd673bdf9f | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 8 | ? ? ? ? 16 | ? ? ? ? ? ? ? ? 16 | ? ? ?  |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

在啟動新的etcd節點前,先向etcd集群聲明添加節點的peer-urls和節點名稱

[root@tiaoban etcd]# etcdctl member add etcd4 --peer-urls=http://192.168.158.9:2380
Member b112a60ec305e42a added to cluster cd30cff36981306b
?
ETCD_NAME="etcd4"
ETCD_INITIAL_CLUSTER="etcd1=http://192.168.10.100:2380,etcd3=http://192.168.10.12:2380,etcd4=http://192.168.10.100:12380,etcd2=http://192.168.10.11:2380"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.10.100:12380"
ETCD_INITIAL_CLUSTER_STATE="existing"

接下來使用docker創建一個版本為3.4.23的etcd節點,運行在192.168.10.100上,使用host網絡模式,endpoints地址為http://192.168.10.100:12379,節點名稱為etcd4。

[root@tiaoban etcd]# mkdir -p /opt/docker/etcd/{conf,data}
[root@tiaoban etcd]# chown -R 1001:1001 /opt/docker/etcd/data/
[root@tiaoban etcd]# cat /opt/docker/etcd/conf/etcd.conf 
# 節點名稱
name: 'etcd4'
# 指定節點的數據存儲目錄
data-dir: '/data'
# 監聽客戶端請求的地址列表
listen-client-urls: "http://192.168.10.100:12379"
# 監聽URL,用于節點之間通信監聽地址
listen-peer-urls: "http://192.168.10.100:12380"
# 對外公告的該節點客戶端監聽地址,這個值會告訴集群中其他節點
advertise-client-urls: "http://192.168.10.100:12379"
# 服務端之間通訊使用的地址列表,該節點同伴監聽地址,這個值會告訴集群中其他節點
initial-advertise-peer-urls: "http://192.168.10.100:12380"
# etcd啟動時,etcd集群的節點地址列表
initial-cluster: "etcd1=http://192.168.10.100:2380,etcd3=http://192.168.10.12:2380,etcd2=http://192.168.10.11:2380,etcd4=http://192.168.10.100:12380"
# etcd集群初始化的狀態,new代表新建集群,existing表示加入現有集群
initial-cluster-state: 'existing'
[root@tiaoban etcd]# docker run --name=etcd4 --net=host -d -v /opt/docker/etcd/data:/data -v /opt/docker/etcd/conf:/conf bitnami/etcd:latest etcd --config-file /conf/etcd.conf
a142f38c785f2b7c217fb15f01ac62addfeb22eeb44da00363b1f7b5ce398439

etcd4啟動后,查看集群節點信息:

[root@tiaoban etcd]# etcdctl endpoint status --cluster -w table
+-----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ? ? ? ?  ENDPOINT ? ? ? ? ? | ? ? ?  ID ? ? ?  | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+-----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|  http://192.168.10.100:2379 | 2e0eda3ad6bc6e1e | ?3.4.23 | ? 20 kB | ? ? ?true | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 11 | ? ? ? ? ? ? ? ? 11 | ? ? ?  |
| ? http://192.168.10.12:2379 | 5d2c1bd3b22f796f | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 11 | ? ? ? ? ? ? ? ? 11 | ? ? ?  |
| http://192.168.10.100:12379 | b112a60ec305e42a | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 11 | ? ? ? ? ? ? ? ? 11 | ? ? ?  |
| ? http://192.168.10.11:2379 | bc34c6bd673bdf9f | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 11 | ? ? ? ? ? ? ? ? 11 | ? ? ?  |
+-----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
更新成員

當etcd節點故障,啟動etcd時報錯**member count is unequal**。如果有保留的數據目錄下的文件時,可以通過使用 member update 命令,在保留 etcd 數據的情況下初始化集群數據,重新構建一個新的etcd集群節點。 模擬192.168.10.100:12380節點故障,但數據目錄文件有備份,啟動一個新的節點,地址為:192.168.10.100:22380

# 停用舊節點
[root@tiaoban etcd]# docker stop etcd4
etcd4
[root@tiaoban etcd]# docker rm etcd4
etcd4
?
# 更新節點地址
[root@tiaoban etcd]# cat conf/etcd.conf 
# 節點名稱
name: 'etcd4'
# 指定節點的數據存儲目錄
data-dir: '/data'
# 監聽客戶端請求的地址列表
listen-client-urls: "http://192.168.10.100:22379"
# 監聽URL,用于節點之間通信監聽地址
listen-peer-urls: "http://192.168.10.100:22380"
# 對外公告的該節點客戶端監聽地址,這個值會告訴集群中其他節點
advertise-client-urls: "http://192.168.10.100:22379"
# 服務端之間通訊使用的地址列表,該節點同伴監聽地址,這個值會告訴集群中其他節點
initial-advertise-peer-urls: "http://192.168.10.100:22380"
# etcd啟動時,etcd集群的節點地址列表
initial-cluster: "etcd1=http://192.168.10.100:2380,etcd2=http://192.168.10.11:2380,etcd3=http://192.168.10.12:2380,etcd4=http://192.168.10.100:22380"
# etcd集群初始化的狀態,new代表新建集群,existing表示加入現有集群
initial-cluster-state: 'existing'
?
# 啟動新節點
[root@tiaoban etcd]# docker run --name=etcd4 --net=host -d -v /opt/docker/etcd/data:/data -v /opt/docker/etcd/conf:/conf bitnami/etcd:3.4.23 etcd --config-file /conf/etcd.conf
03c03ac7e6b50a8600cefe443ecafdb03f8f61f153b1a1138029c1726826d74e
[root@tiaoban etcd]# docker ps
CONTAINER ID ? IMAGE ? ? ? ? ? ? ? ? COMMAND ? ? ? ? ? ? ? ? ? CREATED ? ? ? ? STATUS ? ? ? ? PORTS ? ? NAMES
03c03ac7e6b5 ? bitnami/etcd:3.4.23 ? "/opt/bitnami/script…" ? 3 seconds ago ? Up 3 seconds ? ? ? ? ? ? etcd4

執行更新member操作,指定新的節點地址。

[root@tiaoban etcd]# etcdctl member update b112a60ec305e42a --peer-urls=http://192.168.10.100:22380
Member b112a60ec305e42a updated in cluster cd30cff36981306b

查看集群節點信息,節點信息更新完成。

[root@tiaoban etcd]# etcdctl endpoint status --cluster -w table
+-----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ? ? ? ?  ENDPOINT ? ? ? ? ? | ? ? ?  ID ? ? ?  | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+-----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|  http://192.168.10.100:2379 | 2e0eda3ad6bc6e1e | ?3.4.23 | ? 20 kB | ? ? ?true | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 14 | ? ? ? ? ? ? ? ? 14 | ? ? ?  |
| ? http://192.168.10.12:2379 | 5d2c1bd3b22f796f | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 14 | ? ? ? ? ? ? ? ? 14 | ? ? ?  |
| http://192.168.10.100:22379 | b112a60ec305e42a | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 14 | ? ? ? ? ? ? ? ? 14 | ? ? ?  |
| ? http://192.168.10.11:2379 | bc34c6bd673bdf9f | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 14 | ? ? ? ? ? ? ? ? 14 | ? ? ?  |
+-----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
刪除成員

主要用法如下所示:

etcdctl member remove <memberID> [flags]

模擬192.168.10.100:22379節點下線操作

[root@tiaoban etcd]# docker stop etcd4
etcd4
[root@tiaoban etcd]# docker rm etcd4
etcd4
[root@tiaoban etcd]# etcdctl member remove b112a60ec305e42a
Member b112a60ec305e42a removed from cluster cd30cff36981306b
[root@tiaoban etcd]# etcdctl endpoint status --cluster -w table
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ? ? ? ?  ENDPOINT ? ? ? ?  | ? ? ?  ID ? ? ?  | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://192.168.10.100:2379 | 2e0eda3ad6bc6e1e | ?3.4.23 | ? 20 kB | ? ? ?true | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 16 | ? ? ? ? ? ? ? ? 16 | ? ? ?  |
|  http://192.168.10.12:2379 | 5d2c1bd3b22f796f | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 16 | ? ? ? ? ? ? ? ? 16 | ? ? ?  |
|  http://192.168.10.11:2379 | bc34c6bd673bdf9f | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 6 | ? ? ? ? 16 | ? ? ? ? ? ? ? ? 16 | ? ? ?  |
+----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
以下是 `etcdctl` 命令和選項的中文翻譯:
?
命令:
- `alarm disarm` 停止所有告警
- `alarm list` 列出所有告警
- `auth disable` 禁用身份驗證
- `auth enable` 啟用身份驗證
- `auth status` 返回身份驗證狀態
- `check datascale` 檢查給定服務器端點上不同工作負載的數據存儲內存使用情況
- `check perf` 檢查 etcd 集群的性能
- `compaction` 壓縮 etcd 中的事件歷史記錄
- `defrag` 對具有給定端點的 etcd 成員進行存儲碎片整理
- `del` 刪除指定的鍵或鍵范圍 [key, range_end)
- `elect` 觀察并參與領導者選舉
- `endpoint hashkv` 打印 `--endpoints` 中每個端點的 KV 歷史記錄哈希
- `endpoint health` 檢查 `--endpoints` 標志中指定的端點的健康狀態
- `endpoint status` 打印 `--endpoints` 標志中指定的端點的狀態
- `get` 獲取鍵或鍵范圍
- `help` 任何命令的幫助
- `lease grant` 創建租約
- `lease keep-alive` 保持租約活躍(續租)
- `lease list` 列出所有活躍的租約
- `lease revoke` 撤銷租約
- `lease timetolive` 獲取租約信息
- `lock` 獲取命名鎖
- `make-mirror` 在目標 etcd 集群創建鏡像
- `member add` 向集群中添加成員
- `member list` 列出集群中的所有成員
- `member promote` 將集群中的非投票成員提升為投票成員
- `member remove` 從集群中移除成員
- `member update` 更新集群中的成員
- `move-leader` 將領導權轉移到另一個 etcd 集群成員
- `put` 將給定的鍵放入存儲中
- `role add` 添加新角色
- `role delete` 刪除角色
- `role get` 獲取角色的詳細信息
- `role grant-permission` 給角色授予鍵
- `role list` 列出所有角色
- `role revoke-permission` 從角色中撤銷鍵
- `snapshot restore` 將 etcd 成員快照恢復到 etcd 目錄
- `snapshot save` 將 etcd 節點后端快照存儲到給定文件
- `snapshot status` [已棄用] 獲取給定文件的后端快照狀態
- `txn` 事務處理所有請求
- `user add` 添加新用戶
- `user delete` 刪除用戶
- `user get` 獲取用戶的詳細信息
- `user grant-role` 給用戶授予角色
- `user list` 列出所有用戶
- `user passwd` 更改用戶密碼
- `user revoke-role` 從用戶中撤銷角色
- `version` 打印 etcdctl 的版本
- `watch` 監視鍵或前綴上的事件流
?
選項:
- `--cacert=""` 使用此 CA 包驗證啟用了 TLS 的安全服務器的證書
- `--cert=""` 使用此 TLS 證書文件標識安全客戶端
- `--command-timeout=5s` 短命令的超時時間(不包括撥號超時)
- `--debug[=false]` 啟用客戶端調試日志記錄
- `--dial-timeout=2s` 客戶端連接的撥號超時時間
- `-d, --discovery-srv=""` 查詢描述集群端點的 SRV 記錄的域名
- `--discovery-srv-name=""` 使用 DNS 發現時查詢的服務名稱
- `--endpoints=[127.0.0.1:2379]` gRPC 端點
- `-h, --help[=false]` etcdctl 的幫助
- `--hex[=false]` 將字節字符串打印為十六進制編碼的字符串
- `--insecure-discovery[=true]` 接受描述集群端點的不安全 SRV 記錄
- `--insecure-skip-tls-verify[=false]` 跳過服務器證書驗證(注意:此選項僅應在測試目的下啟用)
- `--insecure-transport[=true]` 禁用客戶端連接的傳輸安全
- `--keepalive-time=2s` 客戶端連接的保活時間
- `--keepalive-timeout=6s` 客戶端連接的保活超時時間
- `--key=""` 使用此 TLS 密鑰文件標識安全客戶端
- `--password=""` 身份驗證的密碼(如果使用此選項,--user 選項不應包含密碼)
- `--user=""` 身份驗證的用戶名[:密碼](如果未提供密碼,將提示輸入)
- `-w, --write-out="simple"` 設置輸出格式(字段,JSON,protobuf,簡單,表格)

數據庫操作命令

增加(put)

添加一個鍵值,基本用法如下所示:

etcdctl put [options] <key> <value> [flags]

常用參數如下所示:

參數功能描述
–prev-kv輸出修改前的鍵值

注意事項:

  • 其中value接受從stdin的輸入內容

  • 如果value是以橫線-開始,將會被視為flag,如果不希望出現這種情況,可以使用兩個橫線代替–

  • 若鍵已經存在,則進行更新并覆蓋原有值,若不存在,則進行添加

示例

[root@tiaoban etcd]# etcdctl put name cuiliang
OK
[root@tiaoban etcd]# etcdctl put location -- -beijing
OK
[root@tiaoban etcd]# etcdctl put foo1 bar1
OK
[root@tiaoban etcd]# etcdctl put foo2 bar2
OK
[root@tiaoban etcd]# etcdctl put foo3 bar3
OK
查詢(get)

查詢鍵值,基本用法如下所示:

etcdctl get [options] <key> [range_end] [flags]

常用參數如下所示:

參數功能描述
–hex以十六進制形式輸出
–limit number設置輸出結果的最大值
–prefix根據prefix進行匹配key
–order對輸出結果進行排序,ASCEND 或 DESCEND
–sort-by按給定字段排序,CREATE, KEY, MODIFY, VALUE, VERSION
–print-value-only僅輸出value值
–from-key按byte進行比較,獲取大于等于指定key的結果
–keys-only僅獲取keys

示例

# 獲取鍵值
[root@tiaoban etcd]# etcdctl get name
name
cuiliang
# 只獲取值
[root@tiaoban etcd]# etcdctl get location --print-value-only
-beijing
# 批量取從foo1到foo3的值,不包括foo3
[root@tiaoban etcd]# etcdctl get foo foo3 --print-value-only
bar1
bar2
# 批量獲取前綴為foo的值
[root@tiaoban etcd]# etcdctl get --prefix foo --print-value-only
bar1
bar2
bar3
# 批量獲取符合前綴的前兩個值
[root@tiaoban etcd]# etcdctl get --prefix --limit=2 foo --print-value-only
bar1
bar2
# 批量獲取前綴為foo的值,并排序
[root@tiaoban etcd]# etcdctl get --prefix foo --print-value-only --order DESCEND
bar3
bar2
bar1
刪除(del)

刪除鍵值,基本用法如下所示:

etcdctl del [options] <key> [range_end] [flags]

常用參數如下所示:

參數功能描述
–prefix根據prefix進行匹配刪除
–prev-kv輸出刪除的鍵值
–from-key按byte進行比較,刪除大于等于指定key的結果

示例

# 刪除name的鍵值
[root@tiaoban etcd]# etcdctl del name
1
# 刪除從foo1到foo3且不包含foo3的鍵值
[root@tiaoban etcd]# etcdctl del foo1 foo3
2
# 刪除前綴為foo的所有鍵值
[root@tiaoban etcd]# etcdctl del --prefix foo
1
更新(put覆蓋)

若鍵已經存在,則進行更新并覆蓋原有值,若不存在,則進行添加。

查詢鍵歷史記錄查詢

etcd在每次鍵值變更時,都會記錄變更信息,便于我們查看鍵變更記錄

監聽命令

watch是監聽鍵或前綴發生改變的事件流, 主要用法如下所示:

etcdctl watch [options] [key or prefix] [range_end] [--] [exec-command arg1 arg2 ...] [flags]

示例如下所示:

# 對某個key監聽操作,當key1發生改變時,會返回最新值
etcdctl watch name
# 監聽key前綴
etcdctl watch name --prefix
# 監聽到改變后執行相關操作
etcdctl watch name --  etcdctl get age

etcdctl watch name – etcdctl put name Kevin,如果寫成,會不會變成死循環,導致無限監視,盡量避免。 示例

監聽單個鍵
# 啟動監聽命令
[root@tiaoban etcd]# etcdctl watch foo
?
#另一個控制臺執行新增命令
[root@tiaoban ~]# etcdctl put foo bar
OK
?
# 觀察控制臺監聽輸出
[root@tiaoban etcd]# etcdctl watch foo
PUT
foo
bar
?
#另一個控制臺執行更新命令
[root@tiaoban ~]# etcdctl put foo bar123
OK
?
# 觀察控制臺監聽輸出
[root@tiaoban etcd]# etcdctl watch foo
PUT
foo
bar
PUT
foo
bar123
?
#另一個控制臺執行刪除命令
[root@tiaoban ~]# etcdctl del foo
1
?
# 觀察控制臺監聽輸出
[root@tiaoban etcd]# etcdctl watch foo
PUT
foo
bar
PUT
foo
bar123
DELETE
foo
同時監聽多個鍵
# 監聽前綴為foo的鍵
[root@tiaoban etcd]# etcdctl watch --prefix foo
# 另一個控制臺執行操作
[root@tiaoban ~]# etcdctl put foo1 bar1
OK
[root@tiaoban ~]# etcdctl put foo2 bar2
OK
[root@tiaoban ~]# etcdctl del foo1
1
# 觀察控制臺輸出
[root@tiaoban etcd]# etcdctl watch --prefix foo
PUT
foo1
bar1
PUT
foo2
bar2
DELETE
foo1
?
?
# 監聽指定的多個鍵
[root@tiaoban etcd]# etcdctl watch -i
watch name
watch location
?
# 另一個控制臺執行操作
[root@tiaoban ~]# etcdctl put name cuiliang
OK
[root@tiaoban ~]# etcdctl del name
1
[root@tiaoban ~]# etcdctl put location beijing
OK
# 觀察控制臺輸出
[root@tiaoban etcd]# etcdctl watch -i
watch name
watch location
PUT
name
cuiliang
DELETE
name
?
PUT
location
beijing

租約命令

租約具有生命周期,需要為租約授予一個TTL(time to live),將租約綁定到一個key上,則key的生命周期與租約一致,可續租,可撤銷租約,類似于redis為鍵設置過期時間。其主要用法如下所示:

etcdctl lease <subcommand> [flags]
添加租約

主要用法如下所示:

etcdctl lease grant <ttl> [flags]

示例:

# 設置60秒后過期時間
[root@tiaoban etcd]# etcdctl lease grant 60
lease 6e1e86f4c6512a2b granted with TTL(60s)
# 把foo和租約綁定,設置成60秒后過期
[root@tiaoban etcd]# etcdctl put --lease=6e1e86f4c6512a29 foo bar
OK
# 租約期內查詢鍵值
[root@tiaoban etcd]# etcdctl get foo
foo
bar
# 租約期外查詢鍵值
[root@tiaoban etcd]# etcdctl get foo
返回為空
查看租約

查看租約信息,以便續租或查看租約是否仍然存在或已過期。 查看租約詳情主要用法如下所示:

etcdctl lease timetolive <leaseID> [options] [flags]

示例:

# 添加一個50秒的租約
[root@tiaoban etcd]# etcdctl lease grant 50
lease 6e1e86f4c6512a32 granted with TTL(50s)
# 將name鍵綁定到6e1e86f4c6512a32租約上
[root@tiaoban etcd]# etcdctl put --lease=6e1e86f4c6512a32 name cuiliang
OK
# 查看所有租約列表
[root@tiaoban etcd]# etcdctl lease list
found 1 leases
6e1e86f4c6512a32
# 查看租約詳情,remaining(6s) 剩余有效時間6秒;--keys 獲取租約綁定的 key
[root@tiaoban etcd]# etcdctl lease timetolive --keys 6e1e86f4c6512a32
lease 6e1e86f4c6512a32 granted with TTL(50s), remaining(6s), attached keys([name])
租約續約

通過刷新 TTL 值來保持租約的有效,使其不會過期。 主要用法如下所示:

etcdctl lease keep-alive [options] <leaseID> [flags]

示例如下所示:

# 設置60秒后過期租約
[root@tiaoban etcd]# etcdctl lease grant 60
lease 6e1e86f4c6512a36 granted with TTL(60s)
# 把name和租約綁定,設置成 60 秒后過期
[root@tiaoban etcd]# etcdctl put --lease=6e1e86f4c6512a36 name cuiliang
OK
# 自動定時執行續約,續約成功后每次租約為60秒
[root@tiaoban etcd]# etcdctl lease keep-alive 6e1e86f4c6512a36
lease 6e1e86f4c6512a36 keepalived with TTL(60)
lease 6e1e86f4c6512a36 keepalived with TTL(60)
lease 6e1e86f4c6512a36 keepalived with TTL(60)
……
刪除租約

通過租約 ID 撤銷租約,撤銷租約將刪除其所有綁定的 key。 主要用法如下所示:

etcdctl lease revoke <leaseID> [flags]

示例如下所示:

# 設置600秒后過期租約
[root@tiaoban etcd]# etcdctl lease grant 600
lease 6e1e86f4c6512a39 granted with TTL(600s)
# 把foo和租約綁定,600秒后過期
[root@tiaoban etcd]# etcdctl put --lease=6e1e86f4c6512a39 foo bar
OK
# 查看租約詳情
[root@tiaoban etcd]# etcdctl lease timetolive --keys 6e1e86f4c6512a39
lease 6e1e86f4c6512a39 granted with TTL(600s), remaining(556s), attached keys([foo])
# 刪除租約
[root@tiaoban etcd]# etcdctl lease revoke 6e1e86f4c6512a39
lease 6e1e86f4c6512a39 revoked
# 查看租約詳情
[root@tiaoban etcd]# etcdctl lease timetolive --keys 6e1e86f4c6512a39
lease 6e1e86f4c6512a39 already expired
# 獲取鍵值
[root@tiaoban etcd]# etcdctl get foo
返回為空
多key同一租約

一個租約支持綁定多個 key

# 設置60秒后過期的租約
[root@tiaoban etcd]# etcdctl lease grant 60
lease 6e1e86f4c6512a3e granted with TTL(60s)
# foo1與租約綁定
[root@tiaoban etcd]# etcdctl put --lease=6e1e86f4c6512a3e foo1 bar1
OK
# foo2與租約綁定
[root@tiaoban etcd]# etcdctl put --lease=6e1e86f4c6512a3e foo2 bar2
OK
# 查看租約詳情
[root@tiaoban etcd]# etcdctl lease timetolive --keys 6e1e86f4c6512a3e
lease 6e1e86f4c6512a3e granted with TTL(60s), remaining(14s), attached keys([foo1 foo2])

租約過期后,所有 key 值都會被刪除,因此:

  • 當租約只綁定了一個 key 時,想刪除這個 key,最好的辦法是撤銷它的租約,而不是直接刪除這個 key。

  • 當租約沒有綁定key時,應主動把它撤銷掉,單純刪除 key 后,續約操作持續進行,會造成內存泄露。

直接刪除key演示:

# 設置租約并綁定 zoo1
[root@tiaoban etcd]# etcdctl lease grant 60
lease 6e1e86f4c6512a43 granted with TTL(60s)
[root@tiaoban etcd]# etcdctl --lease=6e1e86f4c6512a43 put zoo1 val1
OK
# 續約
[root@tiaoban etcd]# etcdctl lease keep-alive 6e1e86f4c6512a43
lease 6e1e86f4c6512a43 keepalived with TTL(60)
?
# 此時在另一個控制臺執行刪除key操作:
[root@tiaoban ~]# etcdctl del zoo1
1
# 單純刪除 key 后,續約操作持續進行,會造成內存泄露
[root@tiaoban etcd]# etcdctl lease keep-alive 6e1e86f4c6512a43
lease 6e1e86f4c6512a43 keepalived with TTL(60)
lease 6e1e86f4c6512a43 keepalived with TTL(60)
lease 6e1e86f4c6512a43 keepalived with TTL(60)
...

撤銷key的租約演示:

# 設置租約并綁定 zoo1
[root@tiaoban etcd]# etcdctl lease grant 50
lease 32698142c52a1717 granted with TTL(50s)
[root@tiaoban etcd]# etcdctl --lease=32698142c52a1717 put zoo1 val1
OK
?
# 續約
[root@tiaoban etcd]# etcdctl lease keep-alive 32698142c52a1717
lease 32698142c52a1717 keepalived with TTL(50)
lease 32698142c52a1717 keepalived with TTL(50)
?
# 另一個控制臺執行:etcdctl lease revoke 32698142c52a1717
?
# 續約撤銷并退出
lease 32698142c52a1717 expired or revoked.
[root@tiaoban etcd]# etcdctl get zoo1
# 返回空

備份恢復命令

主要用于管理節點的快照,其主要用法如下所示:

etcdctl snapshot <subcommand> [flags]
生成快照

其主要用法如下所示:

etcdctl snapshot save <filename> [flags]

示例如下所示:

etcdctl snapshot save etcd-snapshot.db
查看快照

首先把etcd數據庫中的所有數據都必須刪除;rm-rf/var/lib/etcd/*

其主要用法如下所示:

etcdctl snapshot status <filename> [flags]

示例如下所示:

etcdctl snapshot status etcd-snapshot.db -w table
恢復快照

其主要用法如下所示:

etcdctl snapshot restore <filename> [options] [flags]
備份恢復演示
  • 新建一個名為name的key

[root@tiaoban ~]# etcdctl put name cuiliang
OK
[root@tiaoban ~]# etcdctl get name
name
cuiliang
[root@tiaoban ~]# etcdctl endpoint status -w table
+---------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ? ?  ENDPOINT ? ? ? | ? ? ?  ID ? ? ?  | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+---------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 192.168.10.100:2379 | 2e0eda3ad6bc6e1e | ?3.4.23 | ? 20 kB | ? ? ?true | ? ? ?false | ? ? ? ? 4 | ? ? ? ? 10 | ? ? ? ? ? ? ? ? 10 | ? ? ?  |
| ?192.168.10.11:2379 | bc34c6bd673bdf9f | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 4 | ? ? ? ? 10 | ? ? ? ? ? ? ? ? 10 | ? ? ?  |
| ?192.168.10.12:2379 | 5d2c1bd3b22f796f | ?3.4.23 | ? 20 kB | ? ? false | ? ? ?false | ? ? ? ? 4 | ? ? ? ? 10 | ? ? ? ? ? ? ? ? 10 | ? ? ?  |
+---------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
  • 生成快照,創建名為snap.db的備份文件

[root@k8s-work1 ~]# etcdctl snapshot save snap.db
{"level":"info","ts":1679220752.5883558,"caller":"snapshot/v3_snapshot.go:119","msg":"created temporary db file","path":"snap.db.part"}
{"level":"info","ts":"2023-03-19T18:12:32.592+0800","caller":"clientv3/maintenance.go:200","msg":"opened snapshot stream; downloading"}
{"level":"info","ts":1679220752.5924425,"caller":"snapshot/v3_snapshot.go:127","msg":"fetching snapshot","endpoint":"127.0.0.1:2379"}
{"level":"info","ts":"2023-03-19T18:12:32.595+0800","caller":"clientv3/maintenance.go:208","msg":"completed snapshot read; closing"}
{"level":"info","ts":1679220752.597161,"caller":"snapshot/v3_snapshot.go:142","msg":"fetched snapshot","endpoint":"127.0.0.1:2379","size":"25 kB","took":0.008507131}
{"level":"info","ts":1679220752.5973082,"caller":"snapshot/v3_snapshot.go:152","msg":"saved","path":"snap.db"}
Snapshot saved at snap.db
  • 查看備份文件詳情

[root@k8s-work1 ~]# ls -lh snap.db 
-rw------- 1 root root 25K 3月 ?19 18:12 snap.db
[root@k8s-work1 ~]# etcdctl snapshot status snap.db -w table
+----------+----------+------------+------------+
| ? HASH ? | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| 8f097221 | ? ? ? 39 | ? ? ? ? 47 | ? ? ?25 kB |
+----------+----------+------------+------------+
  • 把快照文件傳到其他節點

[root@k8s-work1 ~]# scp snap.db 192.168.10.100:/root ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  100% ? 24KB ? 6.9MB/s ? 00:00 ? ?
[root@k8s-work1 ~]# scp snap.db 192.168.10.12:/root
  • 停止所有節點的etcd服務,并刪除數據目錄

[root@k8s-work1 ~]# rm -rf /var/lib/etcd/*
[root@k8s-work1 ~]# etcdctl snapshot restore test.db
[root@k8s-work1 ~]# cp -r default.etcd/member/ /var/lib/etcd/
[root@k8s-work1 ~]# docker ps -a | grep etcd
[root@k8s-work1 ~]# docker restart 550
[root@k8s-work1 ~]# etcdctl get s
s
1
# 其余兩個節點相同操作

恢復案例

所有 Kubernetes 對象都存儲在 etcd 上。定期備份 etcd 集群數據對于在災難場景(例如丟失所有控制平面節點)下恢復 Kubernetes 集群非常重要。 快照文件包含所有 Kubernetes 狀態和關鍵信息。

在一個基線上為etcd做快照能夠實現etcd數據的備份。通過定期地為etcd節點后端數據庫做快照,etcd就能從一個已知的良好狀態的時間點進行恢復。運行在虛擬機的k8s集群,如果偶遇突然斷電,就可能會部分文件有問題,導致etcd和apiserver起不來,這樣整個集群都無法運行,因此在k8s的集群進行etcd備份十分重要,下面主要演示單master集群和多master集群2個方面。

單master集群

環境準備:kubeadm安裝的一主三從

[root@k8s-01 ~]# kubectl get nodes
NAME ? ? STATUS ? ROLES ? ? ? ? ? ? ? ?  AGE ? VERSION
k8s-01 ? Ready ?  control-plane,master ? 22h ? v1.22.3
k8s-02 ? Ready ?  <none> ? ? ? ? ? ? ? ? 22h ? v1.22.3
k8s-03 ? Ready ?  <none> ? ? ? ? ? ? ? ? 22h ? v1.22.3
k8s-04 ? Ready ?  <none> ? ? ? ? ? ? ? ? 22h ? v1.22.3
[root@k8s-01 ~]#
  1. 先備份etcd數據

[root@k8s-01 kubernetes]#  ETCDCTL_API=3 etcdctl snapshot save /opt/etcd-back/snap.db --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd/peer.key
  1. 創建測試pod

[root@k8s-01 ~]# kubectl get pods
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  READY ? STATUS ?  RESTARTS ? ? ?  AGE
nfs-client-provisioner-69b76b8dc6-6l8xs ? 1/1 ? ? Running ? 7 (3h55m ago) ? 4h43m
nginx-6799fc88d8-5rqg8 ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ? ? 48s
nginx-6799fc88d8-phvkx ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ? ? 48s
nginx-6799fc88d8-rwjc6 ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ? ? 48s
[root@k8s-01 ~]#
  1. 停止etcd和apiserver

control-plane階段用于為API Server、Controller Manager和Scheduler生成靜態Pod配置清單,而etcd階段則為本地etcd存儲生成靜態Pod配置清單,它們都會保存于/etc/kubernetes/manifests目錄中。當前主機上的kubelet服務會監視該目錄中的配置清單的創建、變動和刪除等狀態變動,并根據變動完成Pod創建、更新或刪除操作。因此,這兩個階段創建生成的各配置清單將會啟動Master組件的相關Pod

[root@k8s-01 kubernetes]#  mv /etc/kubernetes/manifests/ /etc/kubernetes/manifests-backup/
[root@k8s-01 kubernetes]# kubectl get pods -A
The connection to the server 192.168.1.128:6443 was refused - did you specify the right host or port?
[root@k8s-01 kubernetes]#

image-20220718230447435

  1. 變更/var/lib/etcd

[root@k8s-01 kubernetes]#  mv /var/lib/etcd /var/lib/etcd.bak
[root@k8s-01 kubernetes]#
  1. 恢復etcd數據

[root@k8s-01 lib]# ETCDCTL_API=3 etcdctl --endpoints="https://127.0.0.1:2379"  --cert="/etc/kubernetes/pki/etcd/server.crt"  --key="/etc/kubernetes/pki/etcd/server.key"  --cacert="/etc/kubernetes/pki/etcd/ca.crt" ? snapshot restore /opt/etcd-back/snap.db  --data-dir=/var/lib/etcd/
  1. 啟動etcd和apiserver,查看pods

[root@k8s-01 lib]#  cd /etc/kubernetes/
[root@k8s-01 kubernetes]#  mv manifests-backup manifests
[root@k8s-01 kubernetes]#  kubectl get pods
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  READY ? STATUS ?  RESTARTS ? ? ? ? AGE
nfs-client-provisioner-69b76b8dc6-6l8xs ? 1/1 ? ? Running ? 12 (2m25s ago) ? 4h48m
[root@k8s-01 ~]#  kubectl get pods -n kube-system
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? READY ? STATUS ?  RESTARTS ? ? ? AGE
calico-kube-controllers-65898446b5-t2mqq ? 1/1 ? ? Running ? 11 (16h ago) ? 21h
calico-node-8md6b ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  21h
calico-node-9457b ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  21h
calico-node-nxs2w ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  21h
calico-node-p7d52 ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  21h
coredns-7f6cbbb7b8-g84gl ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  22h
coredns-7f6cbbb7b8-j9q4q ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  22h
etcd-k8s-01 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  22h
kube-apiserver-k8s-01 ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  22h
kube-controller-manager-k8s-01 ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  22h
kube-proxy-49b8g ? ? ? ? ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  22h
kube-proxy-8wh5l ? ? ? ? ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  22h
kube-proxy-b6lqq ? ? ? ? ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  22h
kube-proxy-tldpv ? ? ? ? ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  22h
kube-scheduler-k8s-01 ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  22h
[root@k8s-01 ~]#

由于3個nginx是備份之后啟動的,所以恢復后都不存在了。

多master集群

環境準備:kubeadm安裝的二主二從

[root@k8s-01 ~]# kubectl get nodes
NAME ? ? STATUS ? ROLES ? ? ? ? ? ? ? ?  AGE ? VERSION
k8s-01 ? Ready ?  control-plane,master ? 16h ? v1.22.3
k8s-02 ? Ready ?  control-plane,master ? 16h ? v1.22.3
k8s-03 ? Ready ?  <none> ? ? ? ? ? ? ? ? 16h ? v1.22.3
k8s-04 ? Ready ?  <none> ? ? ? ? ? ? ? ? 16h ? v1.22.3
[root@k8s-01 etcd-v3.5.4-linux-amd64]# ETCDCTL_API=3 etcdctl --endpoints=https://192.168.1.123:2379,https://192.168.1.124:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd/peer.key member list
58915ab47aed1957, started, k8s-02, https://192.168.1.124:2380, https://192.168.1.124:2379, false
c48307bcc0ac155e, started, k8s-01, https://192.168.1.123:2380, https://192.168.1.123:2379, false
[root@k8s-01 etcd-v3.5.4-linux-amd64]#
  1. 2臺master都需要備份:

[root@k8s-01 ~]# ETCDCTL_API=3 etcdctl --endpoints="https://127.0.0.1:2379"  --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd/peer.key  snapshot save /snap-$(date +%Y%m%d%H%M).db
[root@k8s-02 ~]# ETCDCTL_API=3 etcdctl --endpoints="https://127.0.0.1:2379"  --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/peer.crt --key=/etc/kubernetes/pki/etcd/peer.key  snapshot save /snap-$(date +%Y%m%d%H%M).db
  1. 創建3個測試pod

[root@k8s-01 ~]# kubectl get pods
NAME ? ? ? ? ? ? ? ? ? ?  READY ? STATUS ?  RESTARTS ? AGE
nginx-6799fc88d8-2x6gw ? ?1/1 ? ? Running ? 0 ? ? ? ?  4m22s
nginx-6799fc88d8-82mjz ? ?1/1 ? ? Running ? 0 ? ? ? ?  4m22s
nginx-6799fc88d8-sbb6n ? ?1/1 ? ? Running ? 0 ? ? ? ?  4m22s
tomcat-7d987c7694-552v2 ? 1/1 ? ? Running ? 0 ? ? ? ?  2m8s
[root@k8s-01 ~]#
  1. 停掉Master機器的kube-apiserver和etcd

[root@k8s-01 kubernetes]#  mv /etc/kubernetes/manifests/ /etc/kubernetes/manifests-backup/
[root@k8s-02 kubernetes]#  mv /etc/kubernetes/manifests/ /etc/kubernetes/manifests-backup/
  1. 變更/var/lib/etcd

[root@k8s-01 kubernetes]#  mv /var/lib/etcd /var/lib/etcd.bak
[root@k8s-02 kubernetes]#  mv /var/lib/etcd /var/lib/etcd.bak
  1. 恢復etcd數據,etcd集群用同一份snapshot恢復;

[root@k8s-01 /]# ETCDCTL_API=3 etcdctl snapshot restore /snap-202207182330.db ? ? --endpoints=192.168.1.123:2379 ? ? --name=k8s-01 ?  --cacert=/etc/kubernetes/pki/etcd/ca.crt  --cert=/etc/kubernetes/pki/etcd/peer.crt ? --key=/etc/kubernetes/pki/etcd/peer.key ? ? ? --initial-advertise-peer-urls=https://192.168.1.123:2380 ? ? --initial-cluster-token=etcd-cluster-0 ? ? --initial-cluster=k8s-01=https://192.168.1.123:2380,k8s-02=https://192.168.1.124:2380 ? ?  --data-dir=/var/lib/etcd
[root@k8s-01 /]# scp snap-202207182330.db root@192.168.1.124:/
root@192.168.1.124's password:
snap-202207182330.db ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?100% 4780KB ?45.8MB/s ? 00:00
[root@k8s-02 /]# ETCDCTL_API=3 etcdctl snapshot restore /snap-202207182330.db ? ? --endpoints=192.168.1.124:2379 ? ? --name=k8s-02 ?  --cacert=/etc/kubernetes/pki/etcd/ca.crt  --cert=/etc/kubernetes/pki/etcd/peer.crt ? --key=/etc/kubernetes/pki/etcd/peer.key ? ? ? --initial-advertise-peer-urls=https://192.168.1.124:2380 ? ? --initial-cluster-token=etcd-cluster-0 ? ? --initial-cluster=k8s-01=https://192.168.1.123:2380,k8s-02=https://192.168.1.124:2380 ? ?  --data-dir=/var/lib/etcd

6.master節點上啟動etcd和apiserver,查看pods

[root@k8s-01 lib]#  cd /etc/kubernetes/
[root@k8s-01 kubernetes]#  mv manifests-backup manifests
[root@k8s-02 lib]#  cd /etc/kubernetes/
[root@k8s-02 kubernetes]#  mv manifests-backup manifests
[root@k8s-01 lib]# kubectl get pods
###發現無法看到后創建的pod信息
[root@k8s-01 ~]# kubectl get pods -n kube-system
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? READY ? STATUS ?  RESTARTS ? ? ? AGE
calico-kube-controllers-65898446b5-drjjj ? 1/1 ? ? Running ? 10 (16h ago) ? 16h
calico-node-9s7p2 ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
calico-node-fnbj4 ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
calico-node-nx6q6 ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
calico-node-qcffj ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
coredns-7f6cbbb7b8-mn9hj ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
coredns-7f6cbbb7b8-nrwbf ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
etcd-k8s-01 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 1 ? ? ? ? ? ?  16h
etcd-k8s-02 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
kube-apiserver-k8s-01 ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 2 (16h ago) ?  16h
kube-apiserver-k8s-02 ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
kube-controller-manager-k8s-01 ? ? ? ? ? ? 1/1 ? ? Running ? 2 ? ? ? ? ? ?  16h
kube-controller-manager-k8s-02 ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
kube-proxy-d824j ? ? ? ? ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
kube-proxy-k5gw4 ? ? ? ? ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
kube-proxy-mxmhp ? ? ? ? ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
kube-proxy-nvpf4 ? ? ? ? ? ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
kube-scheduler-k8s-01 ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 1 ? ? ? ? ? ?  16h
kube-scheduler-k8s-02 ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ? ? ?  16h
[root@k8s-01 ~]#

Kubernetes集群升級指南

前言

本文演示kubernetes集群從v1.24.1升級到v1.29.15。

一、集群升級過程輔助命令

(1)查看節點上運行的pod。

kubectl get pod -o wide |grep <nodename>

(2)查看集群配置文件。

kubectl -n kube-system get cm kubeadm-config -o yaml

(3)查看當前集群節點。

kubectl get node

二、升級master節點

2.1、升級kubeadm。

# 更新包管理器
yum update
# 查看可用版本
apt-cache madison kubeadm
yum list | grep kubeadm
# 更新
yum update -y kubeadm
?
# 驗證版本
kubeadm version

2.2、驗證升級計劃

(1)檢查可升級到哪些版本,并驗證你當前的集群是否可升級。

kubeadm upgrade plan
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[preflight] Running pre-flight checks.
[upgrade] Running cluster health checks
[upgrade] Fetching available versions to upgrade to
[upgrade/versions] Cluster version: v1.28.15
[upgrade/versions] kubeadm version: v1.29.15
I0327 11:28:43.151508 1125701 version.go:256] remote version is much newer: v1.32.3; falling back to: stable-1.29
[upgrade/versions] Target version: v1.29.15
[upgrade/versions] Latest version in the v1.28 series: v1.28.15
?
Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT ? CURRENT ? ? ?  TARGET
kubelet ? ? 3 x v1.28.15 ? v1.29.15
?
Upgrade to the latest stable version:
?
COMPONENT ? ? ? ? ? ? ? ? CURRENT ?  TARGET
kube-apiserver ? ? ? ? ?  v1.28.15 ? v1.29.15
kube-controller-manager ? v1.28.15 ? v1.29.15
kube-scheduler ? ? ? ? ?  v1.28.15 ? v1.29.15
kube-proxy ? ? ? ? ? ? ?  v1.28.15 ? v1.29.15
CoreDNS ? ? ? ? ? ? ? ? ? v1.10.1 ?  v1.11.1
etcd ? ? ? ? ? ? ? ? ? ? ?3.5.15-0 ? 3.5.16-0
?
You can now apply the upgrade by executing the following command:
?kubeadm upgrade apply v1.29.15
?
_____________________________________________________________________
?
?
The table below shows the current state of component configs as understood by this version of kubeadm.
Configs that have a "yes" mark in the "MANUAL UPGRADE REQUIRED" column require manual config upgrade or
resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually
upgrade to is denoted in the "PREFERRED VERSION" column.
?
API GROUP ? ? ? ? ? ? ? ? CURRENT VERSION ? PREFERRED VERSION ? MANUAL UPGRADE REQUIRED
kubeproxy.config.k8s.io ? v1alpha1 ? ? ? ?  v1alpha1 ? ? ? ? ?  no
kubelet.config.k8s.io ? ? v1beta1 ? ? ? ? ? v1beta1 ? ? ? ? ? ? no
_____________________________________________________________________

注意下面的MANUAL字段:

The table below shows the current state of component configs as understood by this version of kubeadm.
Configs that have a "yes" mark in the "MANUAL UPGRADE REQUIRED" column require manual config upgrade or
resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually
upgrade to is denoted in the "PREFERRED VERSION" column.
?
API GROUP ? ? ? ? ? ? ? ? CURRENT VERSION ? PREFERRED VERSION ? MANUAL UPGRADE REQUIRED
kubeproxy.config.k8s.io ? v1alpha1 ? ? ? ?  v1alpha1 ? ? ? ? ?  no
kubelet.config.k8s.io ? ? v1beta1 ? ? ? ? ? v1beta1 ? ? ? ? ? ? no
_____________________________________________________________________

指示哪些主鍵需要手動升級,如果是yes就要手動升級。

(2)顯示哪些差異將被應用于現有的靜態 pod 資源清單。

kubeadm upgrade diff 1.29.15
[upgrade/diff] Reading configuration from the cluster...
[upgrade/diff] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
--- /etc/kubernetes/manifests/kube-apiserver.yaml
+++ new manifest
@@ -40,7 +40,7 @@- --service-cluster-ip-range=10.96.0.0/12- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
- ?  image: registry.aliyuncs.com/google_containers/kube-apiserver:v1.28.15
+ ?  image: registry.aliyuncs.com/google_containers/kube-apiserver:1.29.15imagePullPolicy: IfNotPresentlivenessProbe:failureThreshold: 8
--- /etc/kubernetes/manifests/kube-controller-manager.yaml
+++ new manifest
@@ -28,7 +28,7 @@- --service-account-private-key-file=/etc/kubernetes/pki/sa.key- --service-cluster-ip-range=10.96.0.0/12- --use-service-account-credentials=true
- ?  image: registry.aliyuncs.com/google_containers/kube-controller-manager:v1.28.15
+ ?  image: registry.aliyuncs.com/google_containers/kube-controller-manager:1.29.15imagePullPolicy: IfNotPresentlivenessProbe:failureThreshold: 8
--- /etc/kubernetes/manifests/kube-scheduler.yaml
+++ new manifest
@@ -16,7 +16,7 @@- --bind-address=127.0.0.1- --kubeconfig=/etc/kubernetes/scheduler.conf- --leader-elect=true
- ?  image: registry.aliyuncs.com/google_containers/kube-scheduler:v1.28.15
+ ?  image: registry.aliyuncs.com/google_containers/kube-scheduler:1.29.15imagePullPolicy: IfNotPresentlivenessProbe:failureThreshold: 8

2.3、master節點升級

(1)升級到 1.29.15版本,此命令僅升級master節點(control plane)。

kubeadm upgrade apply v1.29.15
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[preflight] Running pre-flight checks.
[upgrade] Running cluster health checks
[upgrade/version] You have chosen to change the cluster version to "v1.29.15"
[upgrade/versions] Cluster version: v1.28.15
[upgrade/versions] kubeadm version: v1.29.15
[upgrade] Are you sure you want to proceed? [y/N]: y
[upgrade/prepull] Pulling images required for setting up a Kubernetes cluster
[upgrade/prepull] This might take a minute or two, depending on the speed of your internet connection
[upgrade/prepull] You can also perform this action in beforehand using 'kubeadm config images pull'
[upgrade/apply] Upgrading your Static Pod-hosted control plane to version "v1.29.15" (timeout: 5m0s)...
[upgrade/etcd] Upgrading to TLS for etcd
[upgrade/staticpods] Preparing for "etcd" upgrade
[upgrade/staticpods] Renewing etcd-server certificate
[upgrade/staticpods] Renewing etcd-peer certificate
[upgrade/staticpods] Renewing etcd-healthcheck-client certificate
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/etcd.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2025-03-27-11-32-38/etcd.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/staticpods] This might take a minute or longer depending on the component/version gap (timeout 5m0s)
[apiclient] Found 1 Pods for label selector component=etcd
[upgrade/staticpods] Component "etcd" upgraded successfully!
[upgrade/etcd] Waiting for etcd to become available
[upgrade/staticpods] Writing new Static Pod manifests to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests2230279311"
[upgrade/staticpods] Preparing for "kube-apiserver" upgrade
[upgrade/staticpods] Renewing apiserver certificate
[upgrade/staticpods] Renewing apiserver-kubelet-client certificate
[upgrade/staticpods] Renewing front-proxy-client certificate
[upgrade/staticpods] Renewing apiserver-etcd-client certificate
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-apiserver.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2025-03-27-11-32-38/kube-apiserver.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/staticpods] This might take a minute or longer depending on the component/version gap (timeout 5m0s)
[apiclient] Found 1 Pods for label selector component=kube-apiserver
[upgrade/staticpods] Component "kube-apiserver" upgraded successfully!
[upgrade/staticpods] Preparing for "kube-controller-manager" upgrade
[upgrade/staticpods] Renewing controller-manager.conf certificate
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-controller-manager.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2025-03-27-11-32-38/kube-controller-manager.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/staticpods] This might take a minute or longer depending on the component/version gap (timeout 5m0s)
[apiclient] Found 1 Pods for label selector component=kube-controller-manager
[upgrade/staticpods] Component "kube-controller-manager" upgraded successfully!
[upgrade/staticpods] Preparing for "kube-scheduler" upgrade
[upgrade/staticpods] Renewing scheduler.conf certificate
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-scheduler.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2025-03-27-11-32-38/kube-scheduler.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/staticpods] This might take a minute or longer depending on the component/version gap (timeout 5m0s)
[apiclient] Found 1 Pods for label selector component=kube-scheduler
[upgrade/staticpods] Component "kube-scheduler" upgraded successfully!
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
[upgrade] Backing up kubelet config file to /etc/kubernetes/tmp/kubeadm-kubelet-config3777955110/config.yaml
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "super-admin.conf" kubeconfig file
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
?
[upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.29.15". Enjoy!
?
[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.

(2) 騰空節點,即將節點上除守護進程之外的其他進程調度到其他節點,同時將開啟調度保護。

kubectl drain <nodename> --ignore-daemonsets
$ kubectl drain k8s-master1 --ignore-daemonsets
node/k8s-master1 cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-flannel/kube-flannel-ds-nxz4d, kube-system/kube-proxy-pbnk4
evicting pod kube-system/coredns-c676cc86f-twm96
evicting pod kube-system/coredns-c676cc86f-mdgbn
pod/coredns-c676cc86f-mdgbn evicted
pod/coredns-c676cc86f-twm96 evicted
node/k8s-master1 drained
?
$ kubectl get pod -A
NAMESPACE ? ?  NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  READY ? STATUS ?  RESTARTS ? AGE
kube-flannel ? kube-flannel-ds-nxz4d ? ? ? ? ? ? ? ? 1/1 ? ? Running ? 0 ? ? ? ?  136m
kube-system ?  coredns-c676cc86f-7stvs ? ? ? ? ? ? ? 0/1 ? ? Pending ? 0 ? ? ? ?  60s
kube-system ?  coredns-c676cc86f-vmkgv ? ? ? ? ? ? ? 0/1 ? ? Pending ? 0 ? ? ? ?  60s
kube-system ?  etcd-k8s-master1 ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ?  11m
kube-system ?  kube-apiserver-k8s-master1 ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ?  10m
kube-system ?  kube-controller-manager-k8s-master1 ? 1/1 ? ? Running ? 0 ? ? ? ?  10m
kube-system ?  kube-proxy-pbnk4 ? ? ? ? ? ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ?  9m44s
kube-system ?  kube-scheduler-k8s-master1 ? ? ? ? ? ?1/1 ? ? Running ? 0 ? ? ? ?  9m58s
?
$ kubectl get node
NAME ? ? ? ?  STATUS ? ? ? ? ? ? ? ? ? ? ROLES ? ? ? ? ? AGE ?  VERSION
k8s-master1 ? Ready,SchedulingDisabled ? control-plane ? 162m ? v1.24.1

(3)升級kubelet與kubectl組件。

yum update -y kubelet

(4)重啟 kubelet。

systemctl daemon-reload
systemctl restart kubelet

(5)解除調度保護。

kubectl uncordon <nodename>

三、升級node節點

(1)升級節點kubelet 配置。

kubeadm upgrade node

(2)騰空節點,同時開啟調度保護,此命令請在master節點操作

kubectl drain <nodename> --ignore-daemonsets

(3)升級kubelet與kubectl組件。

yum update -y kubelet

(4)重啟 kubelet。

systemctl daemon-reload
systemctl restart kubelet

(5)解除調度保護,master節點上執行該命令。

kubectl uncordon <nodename>

總結

每個版本的升級都不一樣,所以要根據版本進行適當調整,不作為萬能指導。 升級過程:

  1. 升級master組件。

  2. 升級worker節點組件,調度保護、排空節點、worker節點組件升級、解除保護。

Kubernetes集群的升級可以分為以下幾個步驟:

  1. 備份數據。在升級之前,需要備份Kubernetes集群的數據,包括訪問控制、配置文件、數據卷等。

  2. 選擇升級方式。Kubernetes集群的升級方式可以分為兩種:滾動升級和強制替換。滾動升級是指逐個升級每個節點,直到所有節點都升級完成。強制替換是指一次性替換所有節點,將舊節點直接替換為新節點。

  3. 準備新版本。Kubernetes升級需要準備新版本的二進制文件和鏡像文件。可以從Kubernetes官方網站下載最新版本的二進制文件和鏡像文件,并上傳到集群中的節點上。

  4. 升級Master節點。首先需要升級Master節點,使用新版本的二進制文件替換舊版本的二進制文件,并啟動新版本的Kubernetes API Server、ControllerKubernetes是一個快速發展的開源項目,為了保持其功能和安全性,集群的升級是必須的。

    • 查看升級文檔:首先需要查看官方的升級文檔,了解升級過程中需要注意的事項。

    • 備份數據:在升級前需要備份當前的數據,以防升級過程中的意外情況導致數據丟失。

    • 準備好備份:在升級前需要確保備份的可用性,以便在需要時能夠 Manager和Scheduler。

  5. 升級Node節點。接下來需要升級Node節點。首先需要將節點上的Kubelet和kube-proxy服務停止,使用新版本的二進制文件替換舊版本的二進制文件,然后啟動新版本的Kubelet和kube-proxy服務。

  6. 驗證升級結果。升級完成后,需要驗證恢復數據。

    • 升級前的測試:可以在測試環境中進行升級測試,以確保升級過程和升級后的集群正常運行。

    • 升級Node:首先需要升級每個Node節點中的Kubernetes組件,包括kubelet和kube-proxy等。

    • 升級Control Plane:然后需要升級Control Plane中的Kubernetes組件,包括kube-apiserver、kube-controller-manager和kube-scheduler等。

    • 升級Kubernetes對象:升級完Control Plane后,需要升級Kubernetes對象,如Deployment集群是否正常運行。可以使用kubectl命令查看集群的狀態和資源對象的狀態,確保所有的服務都能夠正常訪問。

  7. 回滾升級。如果升級失敗或出現問題,可以回滾到之前的版本。回滾的過程與升級的過程相同,只需要使用舊版本的二進制文件和鏡像文件即可。

Kubernetes集群的升級需要仔細規劃和準備,并按照一定的步驟進行操作。只有在備份數據、選擇適當的升級方式、準備新版本、升級Master節點、升級Node節點、驗證升級結果等步驟都完成后,才能確保集群的升級成功。、StatefulSet等。

升級后的檢查:

  • 驗證集群狀態:升級后需要驗證集群的狀態,包括Node節點的狀態、Pod的狀態、Service的狀態等。

  • 驗證應用程序:升級后需要驗證應用程序的運行狀態,確保應用程序正常運行。

  • 觀察日志:如果發現問題,可以通過查看日志來排查問題原因。

Kubernetes集群升級是一個需要謹慎處理的過程,需要充分準備和測試,以確保升級過程的順利和集群的穩定。在升級過程中,需要注意備份數據和備份的可用性,升級順序和升級后的檢查等問題,以確保集群的正常運行和應用程序的穩定性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/95621.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/95621.shtml
英文地址,請注明出處:http://en.pswp.cn/web/95621.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【LeetCode熱題100道筆記】旋轉圖像

題目描述 給定一個 n n 的二維矩陣 matrix 表示一個圖像。請你將圖像順時針旋轉 90 度。 你必須在 原地 旋轉圖像&#xff0c;這意味著你需要直接修改輸入的二維矩陣。請不要 使用另一個矩陣來旋轉圖像。 示例 1&#xff1a;輸入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]…

SpringBoot【集成p6spy】使用p6spy-spring-boot-starter集成p6spy監控數據庫(配置方法舉例)

使用p6spy-spring-boot-starter集成p6spy監控數據庫1.簡單說明2.核心依賴3.主要配置4.簡單測試5.其他配置1.簡單說明 p6spy 類似于 druid 可以攔截 SQL 可以用于項目調試&#xff0c;直接引入 p6spy 的博文已經很多了&#xff0c;這里主要是介紹一下 springboot 使用 p6spy-sp…

擴散模型的優化過程,主要的公式推導,主要是熟悉一下整體的理論框架

核心思想與定義 擴散模型的核心思想是&#xff1a;學習一個去噪過程&#xff0c;以逆轉一個固定的加噪過程。前向過程&#xff08;固定&#xff09;&#xff1a; 定義一個馬爾可夫鏈&#xff0c;逐步向數據 x0~q(x0)\mathbf{x}_0 \sim q(\mathbf{x}_0)x0?~q(x0?) 添加高斯噪…

數字簽名、數字證書、數字信封的概念與區別

要理解數字簽名、數字證書、數字信封&#xff0c;核心是抓住它們各自的核心目標 —— 分別解決 “身份真實性與內容完整性”“公鑰可信度”“數據機密性” 問題&#xff0c;且三者都基于 “非對稱加密”&#xff08;一對公鑰、私鑰&#xff0c;公鑰公開、私鑰保密&#xff0c;用…

Day35 網絡協議與數據封裝

day35 網絡協議與數據封裝 數據封裝與協議結構 以太網MAC幀格式數據封裝與傳輸流程 數據在傳輸過程中&#xff0c;從上層逐層封裝到底層&#xff0c;最終通過物理介質發送。封裝與傳輸的具體流程如下&#xff1a; 封裝過程&#xff08;從IP層到物理層&#xff09; IP層&#xf…

Deeplizard深度學習課程(七)—— 神經網絡實驗

前言我們正在利用pytorch實現CNN。主要分為四個小部分&#xff1a;數據預處理、神經網絡pytorch設計、訓練神經網絡 和 神經網絡實驗。在之前的章節中&#xff0c;我們已經完成了整個CNN框架的設計、訓練與簡單分析&#xff0c;本節將更進一步討論神經網絡處理過程中的細節問題…

STM32實踐項目(激光炮臺)

剛開始設想做一個上半部分可以上下180移動,下半部分底座360移動的激光炮臺。于是便開始了實踐。 所需材料清單: 序號 名稱 數量 備注說明 1 面包板(Breadboard) 2 用于電路搭建和模塊連接 2 杜邦線(公對公、公對母等) 若干 建議準備 30~50 根,方便連接 3 MB-102 電源模塊…

不止是夾住,更是“感知”:Contactile GAL2觸覺型夾爪實現自適應抓取

近日&#xff0c;專注于觸覺傳感與智能抓取技術的Contactile推出全新Contactile 觸覺型夾爪 GAL2&#xff0c;這款集成先進傳感技術的雙指夾爪&#xff0c;憑借實時觸覺反饋能力&#xff0c;為多行業智能抓取場景帶來突破性解決方案。 Contactile 觸覺型夾爪GAL2是一款多功能即…

Grafana - 監控磁盤使用率Variables使用

1 查詢prometheus2 編輯grafana dashboard 2.1 配置變量2.2 配置多選2.3 配置legend2.4 優化顯示 1 查詢prometheus 指標名稱描述node_filesystem_size_bytes文件系統總容量node_filesystem_avail_bytes用戶可用空間node_filesystem_files_free剩余inode數量比如我們想看/目…

WindowsAPI|每天了解幾個winAPI接口之網絡配置相關文檔Iphlpapi.h詳細分析10

上一篇&#xff1a;WindowsAPI|每天了解幾個winAPI接口之網絡配置相關文檔Iphlpapi.h詳細分析9 如果有錯誤歡迎指正批評&#xff0c;在此只作為科普和參考。 C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um\iphlpapi.h 文章目錄GetNetworkParams&#xff1a…

算法 --- 分治(歸并)

分治&#xff08;歸并&#xff09; 分治&#xff08;特別是歸并&#xff09;算法適用于解決“整體求解依賴于子問題合并”且子問題相互獨立的題目&#xff0c;其典型特征是能將大規模數據分解、遞歸求解&#xff0c;然后通過合并操作&#xff08;這正是歸并排序中‘歸并’的精…

【程序人生】有夢想就能了不起,就怕你沒夢想

夢想不是遙不可及的星辰&#xff0c;而是需要我們用腳步丈量的路途兩年前的一個夏日&#xff0c;我在日記本上鄭重地寫下&#xff1a;"我要掌握Web開發&#xff0c;能夠獨立構建一個完整的Web應用。"那天是2023年6月8日&#xff0c;當時的我連Java和JavaScript都分不…

前端基礎(四十二):非固定高度的容器實現折疊面板效果

效果展示源碼 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head>…

發票、收據合并 PDF 小程序,報銷上傳 3 秒搞定

每到報銷、報稅、財務整理時&#xff0c;手里是不是總有一堆格式不一的票據&#xff1a; 聊天記錄里的電子發票郵件附件中的 PDF 發票手機相冊里的報銷收據甚至還有零散的紙質票據掃描件 要上傳或交給財務前&#xff0c;還得一個個整理、轉換、排版&#xff0c;既耗時又容易出…

GitHub每日最火火火項目(9.4)

1. bytebot-ai / bytebot 項目名稱&#xff1a;bytebot項目介紹&#xff1a;基于 TypeScript 開發&#xff0c;是一款自托管的 AI 桌面智能體&#xff0c;能通過自然語言命令自動化執行計算機任務&#xff0c;運行在容器化的 Linux 桌面環境中。它借助自然語言處理和 AI 技術&a…

MMORPG 游戲戰斗系統架構

&#x1f30c; MMORPG 游戲戰斗系統架構 引用&#xff1a; 游戲服務器同步技術解析&#xff08;C&#xff09;MMORPG移動同步與反外掛 雖然我已離開游戲行業&#xff0c;轉而與幾位成功的商人共同創業&#xff0c;投身于商用機器人領域&#xff0c;但坦誠地說&#xff0c;游戲…

【數學建模學習筆記】啟發式算法:蒙特卡洛算法

蒙特卡洛模擬入門筆記&#xff1a;從原理到代碼實踐一、什么是蒙特卡洛模擬&#xff1f;蒙特卡洛模擬是一種通過大量隨機實驗來解決復雜問題的方法。簡單說&#xff0c;就是用電腦模擬成千上萬次隨機事件&#xff0c;然后統計結果&#xff0c;以此估算一個問題的答案。舉個生活…

20250904的學習筆記

一、封包與拆包1. 封包&#xff08;Packet Encapsulation&#xff09;封包 是指在發送數據時&#xff0c;將數據從高層協議封裝到低層協議的過程。每經過一層協議&#xff0c;數據都會被加上相應的協議頭&#xff08;有時也會加上協議尾&#xff09;&#xff0c;形成一個新的數…

STM32F4 + RT-Thread 實戰指南:TIM10 硬件定時器驅動開發與 1 秒定時功能實現

目錄前言一、STM32定時器10是個什么定時器&#xff1f;二、工程創建、環境配置三、程序代碼四、運行前言 在rtthread中&#xff0c;STM32F4的定時器10有些驅動并不完整&#xff0c;對比與其它定時器在使用時需要手動的添加一些代碼&#xff0c;我在使用上拆踩了一些坑&#xf…

echarts圖庫

環形圖// 指定圖表的配置項和數據this.option {// tooltip: {// trigger: item// },color: [#FFB32F, #FF5757, #57D5FF, #2FA8FF, #95FFF1], // 扇形區域以及列表顏色legend: {orient:vertical,//文字橫向排itemGap:20,left: left,textStyle:{color: #F3F9FF,// fontSi…