# etcd 深入探討 ## 安裝 etcdctl * 在 control plane 安裝 etcdctl ``` $ ETCD_RELEASE=$(curl -s https://api.github.com/repos/etcd-io/etcd/releases/latest|grep tag_name | cut -d '"' -f 4) $ wget https://github.com/etcd-io/etcd/releases/download/${ETCD_RELEASE}/etcd-${ETCD_RELEASE}-linux-amd64.tar.gz $ tar zxvf etcd-${ETCD_RELEASE}-linux-amd64.tar.gz $ cp -rp etcd-${ETCD_RELEASE}-linux-amd64/etcdctl /usr/local/bin ``` ## 直接進入 etcd 看資料 * 建立一個持續 CrashLoopBackOff 的 pod ``` $ kubectl create deploy crash --image=quay.io/hahappyman/myapp $ kubectl get pod NAME READY STATUS RESTARTS AGE crash-85bcfd65f6-mh8bq 1/2 CrashLoopBackOff 1 (108s ago) <invalid> # 查看 pod 的相關 event $ kubectl describe pod -l app=crash ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 34s default-scheduler Successfully assigned default/crash-556c4f5dcc-whtz7 to tk8s-worker1 Normal Pulled 32s kubelet Successfully pulled image "quay.io/hahappyman/myapp" in 739ms (739ms including waiting). Image size: 1302385 byte s. Normal Pulled 30s kubelet Successfully pulled image "quay.io/hahappyman/myapp" in 837ms (837ms including waiting). Image size: 1302385 byte s. Normal Pulling 15s (x3 over 33s) kubelet Pulling image "quay.io/hahappyman/myapp" Normal Created 14s (x3 over 32s) kubelet Created container: myapp Normal Started 14s (x3 over 32s) kubelet Started container myapp Normal Pulled 14s kubelet Successfully pulled image "quay.io/hahappyman/myapp" in 866ms (866ms including waiting). Image size: 1302385 byte s. Warning BackOff 1s (x4 over 30s) kubelet Back-off restarting failed container myapp in pod crash-556c4f5dcc-whtz7_default(5c4fb69e-2678-4d67-8733-64337123 36e2) ``` * 宣告憑證,後續使用 etcdctl 就不用再手動加憑證,需注意自己的 endpoints 位置。 ``` $ alias etcdctl="ETCDCTL_API=3 /usr/local/bin/etcdctl \ --endpoints=172.22.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/apiserver-etcd-client.crt \ --key=/etc/kubernetes/pki/apiserver-etcd-client.key" ``` * 直接看 etcd 儲存 pod 的內容。 * 可以看到 pod 目前狀態是 CrashLoopBackOff,並且這裡也會存放 pod 的 event 資訊 ``` # 找 crash pod 的 key 名稱 $ etcdctl get /registry --prefix --keys-only |grep pods ....... /registry/pods/default/crash-556c4f5dcc-whtz7 $ etcdctl get /registry/pods/default/crash-556c4f5dcc-whtz7 ...... CrashLoopBackOffyback-off 2m40s restarting failed container=myapp pod=crash-556c4f5dcc-whtz7_default(5c4fb69e-2678-4d67-8733-6433712336e2)vtComplete:Mcontainerd://988e4e 62096813472d8f055b97319df9322e4ccfdaecd1c31ca3cb13228b86cf (2quay.io/hahappyman/myapp:latest:`quay.io/hahappyman/myapp@sha256:8b5ade73d8c28d7168958e4290479dd746f07c706f1c798 fb732d7336675c208BMcontainerd://988e4e62096813472d8f055b97319df9322e4ccfdaecd1c31ca3cb13228b86cfHbR kube-api-access-wx56l-/var/run/secrets/kubernetes.io/serviceaccountDisabledJ BestEffortZb ```  ## 問題探討 * 如果 etcd 會存放 pod 生命狀態和 pod 的即時 event,那麼 etcd 對於網路與 Disk I/O 效能都會非常要求。 * etcd 官網要求的網路與 Disk I/O 效能 : https://etcd.io/docs/v3.4/op-guide/performance/ * 如果 etcd 備份了 crash 的 pod,那麼 restore etcd 時,是不是 crash 的 pod 也會一起被復原? ## etcd 效能優化 ### Time parameters tuning * 適當調整 etcd 的 leader 選舉的心跳時間。如果心跳間隔太低,etcd 將發送不必要的訊息,增加 CPU 和網路資源的使用率。 - `heartbeat-interval`:定義 etcd leader 向 follower 發送心跳的時間間隔,單位為毫秒,預設為 100 毫秒。 - `election-timeout`:當 follower 在指定時間內(毫秒)沒有收到 leader 的心跳,就會觸發新的 leader 選舉,單位為毫秒,預設為 1000 毫秒。 * 可以使用 ping 來測試每個 etcd 之間的 RTT 延遲時間,如果 ping 是 10ms,那麼 `heartbeat-interval` 參數就要設他的(RTT) 0.5 ~ 1.5 倍(5~15)。 * 而 `election-timeout` 至少為 RTT 的 10 倍(100)。 * `heartbeat-interval` 和 `election-timeout` 要整個叢集一致。如果某些節點設太短,某些太長,會導致整個叢集不穩。 ### Snapshots tuning * 為了避免產生巨大的 log,etcd 會定期進行快照,這些快照會保存系統的當前狀態。etcd 為了避免太頻繁做快照(會耗 CPU 與 I/O),會等到變更次數累積到一定數量才產生快照。 - `snapshot-count` : 到達 etcd 的累積變更次數後才做快照,預設為 10,000。 ### Disk tuning * 設定 etcd Disk I/O 的優先權,Disk 優先權可以配置為 ionice,使其高於其他 process,但又不能太高以至於壓垮伺服器。 ``` # best effort, highest priority $ sudo ionice -c2 -n0 -p `pgrep etcd` ``` ## etcd IO 效能測試 * 根據不同環境調整 `tolerations`、`nodeSelector` * `quay.io/cloud-bulldozer/etcd-perf` 這張 image 是使用 fio 指令來驗證 etcd 所在的節點,底層的 Disk IO 效能是否足夠。 ``` $ echo 'apiVersion: v1 kind: Pod metadata: name: etcd-perf spec: restartPolicy: Never initContainers: - name: etcd-perf image: quay.io/cloud-bulldozer/etcd-perf volumeMounts: - name: etcd-data mountPath: /var/lib/etcd containers: - name: wait image: busybox command: ["sh", "-c", "sleep infinity"] lifecycle: postStart: exec: command: - /bin/sh - -c - | rm -rf /var/lib/etcd/etcd_perf.0.0 volumeMounts: - name: etcd-data mountPath: /var/lib/etcd volumes: - name: etcd-data hostPath: path: /var/lib/etcd type: Directory tolerations: - key: "node-role.kubernetes.io/control-plane" operator: "Exists" effect: "NoSchedule" nodeSelector: kubernetes.io/hostname: "tk8s-control-plane"' | kubectl apply -f - ``` * 檢查 log,以 10 ms 為基準,如果超過這個數值就會被判定為 etcd IO 效能太差。 ``` $ kubectl get pod NAME READY STATUS RESTARTS AGE etcd-perf 1/1 Running 0 108s $ kubectl logs etcd-perf -c etcd-perf ...... INFO: 99th percentile of fsync is 7176192 ns INFO: 99th percentile of the fsync is within the recommended threshold: - 10 ms, the disk can be used to host etcd $ kubectl delete pod etcd-perf ``` ## 參考 https://etcd.io/docs/v3.4/tuning/
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up