我们都知道Kubernetes是一个分布式平台,它编排不同的工作节点,并且可以由中心主节点控制。可以有n个分布式的工作节点处理pod。为了完成跟踪这些节点的所有更改、更新、传递所需的操作, Kubernetes使用etcd。
Kubernetes中的etcd是什么?
etcd是一种简单、快速、安全的分布式可靠键值存储。它类似于后端服务发现和数据库,同时在Kubernetes集群中的不同服务器上运行,以监视集群中的更改,并存储应该由Kubernetes主机或集群访问的状态/配置数据。此外,etcd允许Kubernetes master支持发现服务,以便部署的应用程序可以声明其可用性以包含在服务中。
Kubernetes主节点中的API服务器组件与etcd通信,这些组件分布在不同的集群中。etcd还可用于设置系统的所需状态。
通过对Kubernetes-etcd的键值存储,存储了Kubernetes集群的所有配置。它不同于传统的以表格形式存储数据的数据库。etcd为每个记录创建一个数据库页,在更新一条记录时不会妨碍其他记录。例如,可能会发生这样的情况:少数记录可能需要额外的列,但同一数据库中的其他记录不需要这些列。这会在数据库中创建冗余。etcd以可靠的方式为Kubernetes添加和管理所有记录。
分布的和一致的
etcd为Kubernetes存储关键数据。通过分布式,它还维护分布式机器/服务器上所有集群的数据存储副本。此副本对于所有数据存储区都是相同的,并维护来自所有其他etcd数据存储区的相同数据。即使一个副本被破坏,还有另两个保存着相同的信息。
Kubernetes集群中etcd的部署方法
etcd的实现是以这样一种方式构建的,以实现Kubernetes中的高可用性。etcd可以作为pod部署在主节点上。
它也可以部署在外部以实现弹性和安全性:
etcd的工作原理
etcd是Kubernetes集群的大脑。使用etcd的“Watch”功能监控更改序列。通过这个功能,Kubernetes可以订阅集群内的更改并执行来自API服务器的任何状态请求。etcd与分布式集群中的不同组件协作。etcd对组件状态的更改作出反应,其他组件可能会对更改作出反应。
可能存在这样一种情况:在维护集群中一组etcd组件的所有状态的相同副本时,需要将相同的数据存储在两个etcd实例中。但是,etcd不应该在不同的实例中更新相同的记录。
在这种情况下,etcd不会处理每个集群节点上的写操作。相反,只有一个实例负责在内部处理写操作。那个节点叫做leader。集群内其他节点采用RAFT算法选择一个leader。一旦leader选定,其他节点就成为follower节点。
现在,当写请求到达leader节点时,leader处理写入。leader etcd节点向其他节点广播数据的副本。如果一个follower节点在那一刻处于不活动或脱机状态,那么基于大多数可用节点,写请求将得到一个完整的标志。通常,如果leader得到集群中其他成员的同意,写操作将获得完整标志。
这是它们选择leader,以及如何确保在所有实例中传播写操作的方式。利用raft协议在etcd中实现了这种分布式共识。
etcd中集群的工作方式
Kubernetes是由CoreOS发起的etcd项目的主要用户。etcd已经成为Kubernetes集群pod功能和整体跟踪的规范。Kubernetes支持各种集群架构——这些架构可能包含etcd作为关键组件,或者可能包含多个主节点,且etcd作为独立组件。
在任何特定架构中,每个系统配置的etcd角色都会发生变化。可以实现这种etcd的动态布局来管理集群,以提高扩展性。结果是很容易支持和管理工作负载。
下面是在Kubernetes中启动etcd的步骤。
Wget etcd文件:
wget -q --show-progress --https-only --timestamping \ "https://github.com/etcd-io/etcd/releases/download/v3.4.0/etcd-v3.4.0-linux-amd64.tar.gz"
{
tar -xvf etcd-v3.4.0-linux-amd64.tar.gz
sudo mv etcd-v3.4.0-linux-amd64/etcd* /usr/local/bin/
}
{
sudo mkdir -p /etc/etcd /var/lib/etcd
sudo cp ca.pem kubernetes-key.pem kubernetes.pem /etc/etcd/
}
获取当前计算实例的内部IP地址。它将用于处理客户端请求和与etcd集群对等方的数据传输:
INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \ http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip)
ETCD_NAME=$(hostname -s)
cat <<EOF | sudo tee /etc/systemd/system/etcd.service[Unit]
Description=etcd
Documentation=https://github.com/coreos
[Service]
Type=notify
ExecStart=/usr/local/bin/etcd \\
--name ${ETCD_NAME} \\
--cert-file=/etc/etcd/kubernetes.pem \\
--key-file=/etc/etcd/kubernetes-key.pem \\
--peer-cert-file=/etc/etcd/kubernetes.pem \\
--peer-key-file=/etc/etcd/kubernetes-key.pem \\
--trusted-ca-file=/etc/etcd/ca.pem \\
--peer-trusted-ca-file=/etc/etcd/ca.pem \\
--peer-client-cert-auth \\
--client-cert-auth \\
--initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\
--listen-peer-urls https://${INTERNAL_IP}:2380 \\
--listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\
--advertise-client-urls https://${INTERNAL_IP}:2379 \\
--initial-cluster-token etcd-cluster-0 \\
--initial-cluster controller-0=https://10.240.0.10:2380,controller-1=https://10.240.0.11:2380,controller-2=https://10.240.0.12:2380 \\
--initial-cluster-state new \\
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
Initiate etcd Server
{
sudo systemctl daemon-reload
sudo systemctl enable etcd
sudo systemctl start etcd
}
在控制器0、控制器1和控制器2上重复上述命令。
列出etcd集群成员:
sudo ETCDCTL_API=3 etcdctl member list \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/etcd/ca.pem \
--cert=/etc/etcd/kubernetes.pem \
--key=/etc/etcd/kubernetes-key.pem
输出:
3a57933972cb5131, started, controller-2, https://10.240.0.12:2380, https://10.240.0.12:2379
f98dc20bce6225a0, started, controller-0, https://10.240.0.10:2380, https://10.240.0.10:2379
ffed16798470cab5, started, controller-1, https://10.240.0.11:2380, https://10.240.0.11:2379
结论
etcd是一个独立项目。但是,Kubernetes社区已经广泛使用它来管理集群的状态,从而进一步实现动态工作负载的自动化。将Kubernetes与etcd结合使用的主要好处是,etcd本身就是一个与分布式Kubernetes集群协同工作的分布式数据库。因此,将etcd与Kubernetes结合使用对于集群的健康至关重要