[譯]走進Kubernetes集群的大腦:Etcd


英文原文:A Closer Look at Etcd: The Brain of a Kubernetes Cluster

譯文原文:[譯]走進Kubernetes集群的大腦:Etcd

譯者:野生程序元

Etcd是Kubernetes用於存儲集群各種狀態信息(配置信息,運行)一個很重要的組件,這篇文章,我們帶領大家掀開Etcd的神秘面紗,理解他是如何存儲這些各種各樣的碎片信息的。

Etcd的概況

Etcd 是一個分布式的,依賴key-value存儲的,最重要的分布式數據存儲系統 

-- etcd.io


在Kubernetes的世界里面,etcd是服務發現集群狀態存儲以及其配置的基石。

Etcd以集群部署,節點間通信是通過Raft算法處理。在生產環境中,集群包含至少3個節點。在 thesecretlivesofdata.com/ 中使用動畫很好地地解釋了Raft算法如何運作以及整個集群的生命周期,包含以下幾點

  • leader節點的選舉
  • 日志的復制與同步

Kubernetes中的Etcd

在Kubernetes集群的背景下,etcd實例可以作為Pod被部署在master節點上。下面是我們這篇文章會使用的Kubernetes模型。

如果想增加安全校驗與彈性伸縮的功能的話,也可以將etcd部署成一個內部集群。

下面這個時序圖來自Hepio的博客,展示了當一個Pod被創建的時候,Kubernetes內部模塊之間的處理流程,形象地闡述了API Server和etcd之間的相互作用。

Kubernetes測試集群

這個部分我們使用在DigitalOceankubeadm創建一個3節點的Kubernetes測試集群,選擇weavenet作為網絡附加組件。這個集群的etcd運行在master節點上。我們並沒有配置一個真實環境的HA集群,但已經足夠我們去探索etcd的數據存儲功能了。

$ kubectl get nodes
NAME    STATUS ROLES  AGE   VERSION
node-01 Ready  master 56m   v1.15.2
node-02 Ready  <none> 2m17  v1.15.2
node-03 Ready  <none> 2m17  v1.15.2

Etcd Pod

首先,我們將集群中所有正在運行的Pods先列出來:

$ kubectl get pods --all-namespaces
NAMESPACE   NAME                           READY STATUS  RESTART AGE
kube-system coredns-5c98db65d4–5kjjv       1/1   Running 0       57m
kube-system coredns-5c98db65d4–88hkq       1/1   Running 0       57m
kube-system etcd-node-01                   1/1   Running 0       56m
kube-system kube-apiserver-node-01         1/1   Running 0       56m
kube-system kube-controller-manager-node-01 1/1  Running 0       56m
kube-system kube-proxy-7642v               1/1   Running 0       3m
kube-system kube-proxy-jsp4r               1/1   Running 0       3m
kube-system kube-proxy-xj8qm               1/1   Running 0       57m
kube-system kube-scheduler-node-01         1/1   Running 0       56m
kube-system weave-net-2hvbx                2/2   Running 0       87s
kube-system weave-net-5mrjl                2/2   Running 0       87s
kube-system weave-net-c76fx                2/2   Running 0       87s

當一個集群剛被初始化的時候,只有在namespace為kube-system中的Pod是運行狀態的。這些Pod是用來作為集群的任務管理的。我們比較關心的Pod是etcd-node-01,他是一個ectd的實例,用於存儲集群狀態。

我們運行一個shell命令,進入到這個Pod里面並且查看這個ctcd container的配置

通過使用--advertise-client-urls標識我們可以拿到所有的key/value對,通過etcdctl命令將他們保存到etcd-kv.json

$ ADVERTISE_URL="https://134.209.178.162:2379"

$ kubectl exec etcd-node-01 -n kube-system -- sh -c \
"ETCDCTL_API=3 etcdctl \
--endpoints $ADVERTISE_URL \
--cacert /etc/kubernetes/pki/etcd/ca.crt \
--key /etc/kubernetes/pki/etcd/server.key \
--cert /etc/kubernetes/pki/etcd/server.crt \
get \"\" --prefix=true -w json" > etcd-kv.json

我們快速查看一下這個文件,所有的key對應的values,並且所有都編碼成了base64。

我們先獲取所有的key到一個text文件里面看看他們都長什么樣子,我將所有的key都列出來了,所以有點點長。

$ for k in $(cat etcd-kv.json | jq '.kvs[].key' | cut -d '"' -f2); do echo $k | base64 --decode; echo; done

/registry/apiregistration.k8s.io/apiservices/v1.
/registry/apiregistration.k8s.io/apiservices/v1.apps
/registry/apiregistration.k8s.io/apiservices/v1.authentication.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.authorization.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.autoscaling
/registry/apiregistration.k8s.io/apiservices/v1.batch
/registry/apiregistration.k8s.io/apiservices/v1.coordination.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.networking.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.rbac.authorization.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.scheduling.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1.storage.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1beta1.admissionregistration.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1beta1.apiextensions.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1beta1.apps
/registry/apiregistration.k8s.io/apiservices/v1beta1.authentication.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1beta1.authorization.k8s.io
/registry/apiregistration.k8s.io/apiservices/v1beta1.batch
# 后面有很多,已省略
...

上面顯示了一共342個定義在配置文件中的key,包含所有在集群里面的資源:

  • Nodes
  • Namespaces
  • ServiceAccounts
  • Roles,RolesBindings, ClusterRoles/ClusterRoleBindings
  • ConfigMaps
  • Secrets
  • Workloads: Deployments, DaemonSets, Pods, …
  • Cluster’s certificates
  • The resources within each apiVersion
  • The events that bring the cluster in the current state

如果我們選擇以上其中一個key,我們可以得到具體與之關聯的value通過以下命令:

$ kubectl exec etcd-node-01 -n kube-system —- sh -c \
"ETCDCTL_API=3 etcdctl \
--endpoints $ADVERTISE_URL \
--cacert /etc/kubernetes/pki/etcd/ca.crt \
--key /etc/kubernetes/pki/etcd/server.key \
--cert /etc/kubernetes/pki/etcd/server.crt \
get \"KEY\" -w json"

舉個例子,我們想獲得/registry/deployments/kube-system/coredns這個key的value

如果我們將這個對應的value解碼出來發現信息其實可讀性不高,一些圖表不能被正常解碼顯示,但當然,Kubernetes內部是知道如何正確處理他們的。

從這個結果上看,我們可以推斷出這個key是用來存儲credns這個Pod的規則以及部署狀態的。

創建一個Pod

讓我們一起來創建一個Pod,看看集群的狀態修改了什么以及有什么新的key的增加。

$ cat <<EoF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: www
spec:
  containers:
  - name: nginx
    image: nginx:1.16-alpine
EoF

和之前一樣的命令,我們獲取所有的key並保存在etcd-kv-after-nginx-pod.json中。快速對比一下我們創建Pod之前的key列表和我們創建完wwwPod以后多了什么信息。

> /registry/events/default/www.15b9e3051648764f
> /registry/events/default/www.15b9e3056b8ce3f0
> /registry/events/default/www.15b9e306918312ea
> /registry/events/default/www.15b9e306a32beb6d
> /registry/events/default/www.15b9e306b5892b60
> /registry/pods/default/www

5個event以及一個pod被創建了,並且看上去也十分合理。我們更深入地看一下,從解碼event key所對應的value開始,按照時間排序,我們可以看到他們做了下面的事情:

  • 成功指派default/wwwnode-02
  • 拉取鏡像nginx:1.16-alpine
  • 成功拉取鏡像nginx:1.16-alpine
  • 創建nginxcontainer
  • 啟動這個container

這些事件可以通過下面命令查看:

kubectl describe pod www

最后一個key,/registry/pods/default/www,提供了這個新創建的pod的所有信息

  • 最后使用的配置
  • 關聯的token
  • 狀態
  • ...

(依然解碼出來可讀性很糟糕。)

總結

這篇文章的目的不是深入etcd,而是解釋了一小部分Kubernetes內部包含了什么信息以及這些信息是怎么被組織起來的。希望能填補你對Kubernetes的一小片空白。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM