Etcd是Kubernetes的关键组件,因为它存储了集群的整个状态:其配置,规格以及运行中的工作负载的状态。在本文中,我们将会揭开其神秘的面纱,了解etcd如何存储所有这些信息。
Etcd 简介
Etcd被定义为分布式,可靠的键值存储,用于分布式系统中最关键的数据。
在Kubernetes世界中,etcd用作服务发现的后端,并存储集群的状态及其配置。
Etcd被部署为一个集群,几个节点的通信由Raft算法处理。在生产环境中,集群包含奇数个节点,并且至少需要三个。在 http://thesecretlivesofdata.com/ 中,您可以找到一个很好的动画,说明该算法的运行方式,它说明了集群生命周期的几个阶段,其中包括:
- 选主
- 日志复制
Kubernetes 中的 Etcd
在Kubernetes集群的上下文中,etcd实例可以作为Pod部署在master节点上(这是我们将在本文中使用的示例)。
为了增加安全性和弹性,还可以将其部署为外部集群。
以下来自Heptio博客的序列图显示了在简单的Pod创建过程中涉及的组件。它很好地说明了API服务器和etcd的交互作用。
Kubernetes 测试集群
在本篇文章中,我们使用的Kubernetes集群,由kubeadm创建的三个节点组成,其中一个master节点运行了Etcd。所选的网络附加组件是weavenet。这种配置不适合实际的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
The Etcd Pod
首先,让我们列出集群中运行的所有Pod:
$ 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
由于集群刚刚被初始化,因此只有kube-system名称空间中的Pod正在运行。这些Pod负责集群的管理任务。我们感兴趣的Pod是etcd-node-01
,它运行etcd的实例来负责存储集群的状态。
首先,在etcd Pod中运行一个shell,并检查其中运行的etcd容器的配置:
使用--advertise-client-urls
标志的值,我们可以使用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
快速查看此文件将显示健列表及其对应的值,它们均以base64编码(此处仅显示文件的摘录)。
首先让我们以纯文本格式获取所有键,以查看其内容。我把所有键输出:
$ 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/v