前言
什么是 Etcd
Etcd
是一个 开源的、分布式的、一致性 的 键值存储系统,由 CoreOS
开发和维护。Etcd
使用 Raft
算法实现分布式一致性,提供了 高可用、高可靠、高性能 的数据存储服务。
Etcd
可以被用于存储和检索键值对数据,支持事务和版本控制,并具有分布式一致性和高可用性等特性。Etcd
还提供了 RESTful API
和 gRPC API
,方便用户进行访问和使用。
在 Kubernetes
中,Etcd
被用作数据存储,用于存储集群的元数据和状态信息,包括 Pod
、Service
、ConfigMap
、Secret
等对象的元数据和状态,以及节点的状态和配置信息等。Etcd 在 Kubernetes 中的主要作用是提供一个高可靠、高性能、分布式的数据存储系统,用于管理 Kubernetes
集群中各种对象的元数据和状态信息,从而实现集群的高效运行和管理。
除了
k8s
外,Etcd
还被广泛应用于微服务架构、配置管理、服务发现 等场景,成为了一个重要的 分布式系统基础组件。
为啥 K8S 要选择 Etcd
让我们看看聪明的 ChatGPT 是怎么分析这个问题的:
我也试着问了为啥其他如
Redis
、Mysql
、MongoDB
、Zookeeper
等为何不适合:
其他的回答就不用看了,
ChatGPT
已经成为了复读机了哈,总而言之,如前面介绍中凸显的 Etcd 特点:
- 高可用
- 分布式
- 数据一致性
- 高性能
最终它成为了 K8S 的首选存储系统!
🔔 本文章以集群构建为主,后续再考虑出一篇文章单独介绍 Etcd的架构和原理!
环境准备
当前的环境准备均以博主本身的实际配置出发,如果使用的系统版本和环境有区别,可能搭建流程会有不一样,但是原理差不多,碰到问题的情况可以留言和博主以及小伙伴们一起讨论看看!
机器准备
机器名 | 机器外部IP | 机器内网IP |
---|---|---|
k8sdev001 | 10.12.3.40 | 192.168.3.35 |
k8sdev002 | 10.12.3.41 | 192.168.3.34 |
k8sdev003 | 10.12.3.42 | 192.168.3.33 |
系统和软件版本
环境 | 版本 |
---|---|
CentOS | 7.4.1708 |
etcd | 3.3.11 |
cfssl | 1.6.3 |
配置 hosts
下面的机器命名和服务域名定义均是博主个人喜好,大家可以按照自己的习惯变更!
# hostname resolve
192.168.3.35 k8sdev001
192.168.3.34 k8sdev002
192.168.3.33 k8sdev003
# etcd cluster
192.168.3.35 etcd01-dev.inner.com
192.168.3.34 etcd02-dev.inner.com
192.168.3.33 etcd03-dev.inner.com
安装必备软件
博主使用的是 root
用户进行操作,如果您当前的用户没有权限,请记得切换 root
用户或者使用 sudo
进行操作!
安装 cfssl
cd /tmp
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.3/cfssl_1.6.3_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.3/cfssljson_1.6.3_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.3/cfssl-certinfo_1.6.3_linux_amd64
chmod +x cfssl_1.6.3_linux_amd64 cfssljson_1.6.3_linux_amd64 cfssl-certinfo_1.6.3_linux_amd64
mv cfssl_1.6.3_linux_amd64 /usr/local/bin/cfssl
mv cfssljson_1.6.3_linux_amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_1.6.3_linux_amd64 /usr/local/bin/cfssl-certinfo
安装 etcd
此处博主使用系统默认的安装命令安装,因为对应 etcd 版本刚好是 3.3.11
。
yum install etcd
如果您想自己指定版本安装,可以参考如下命令(GPT
式教程):
# 安装依赖包
yum install -y curl wget tar
# 下载对应版本的压缩包,此处使用 v3.3.11
cd /tmp
wget https://github.com/coreos/etcd/releases/download/v3.3.11/etcd-v3.3.11-linux-amd64.tar.gz
tar -xzf etcd-v3.3.11-linux-amd64.tar.gz
cd etcd-v3.3.11-linux-amd64/
# 将 etcd 和 etcdctl 可执行文件复制到 /usr/local/bin 目录下
cp etcd /usr/local/bin/
cp etcdctl /usr/local/bin/
# 创建 etcd 的数据目录和日志目录
mkdir -p /var/lib/etcd/
mkdir -p /var/log/etcd/
构建集群
生成自签名证书
CFSSL
(CloudFlare SSL)是一个开源的 PKI/TLS
工具包,用于创建、签署、验证 SSL 证书。
它是由 CloudFlare 公司开发并开源的,目的是提供一个轻量级、易于使用的工具包,以便开发人员可以更轻松地设置自己的 PKI/TLS
系统。
CFSSL
支持多种证书颁发机构(CA)的配置,并且可以使用 JSON
或 YAML
配置文件定义证书和请求。
如果您比较熟悉
openssl
,也可以使用openssl
进行自签名!
# 创建存放密钥的文件夹
mkdir -p /etc/etcd/etcd-certs
# 下面的操作都在该文件夹下面进行
cd /etc/etcd/etcd-certs
# 创建 CA 配置文件
# expiry 为签名过期时长
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"expiry": "876000h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
# 创建证书签名请求文件(请根据自己实际情况更新 names 里面的内容)
cat > ca-csr.json <<EOF
{
"CN": "kubernetes",
"key":
{
"algo": "rsa",
"size": 2048
},
"names":
[
{
"C": "CN",
"ST": "GuangDong",
"L": "GuangDong",
"O": "k8s",
"OU": "System"
}
]
}
EOF
# 创建 etcd 证书配置文件 etcd-csr.json
# hosts 把之后会对外暴露的域名、服务器名字、内外网IP都加上吧,然后是否对外通过防火墙控制就好,这样比较大程度能增加后期维护的扩展性
# names 信息和 ca-csr.json 保持一致
cat > kubernetes-csr.json << EOF
{
"CN": "kubernetes",
"hosts":
[
"10.12.3.40",
"10.12.3.41",
"10.12.3.42",
"192.168.3.35",
"192.168.3.34",
"192.168.3.33",
"etcd01-dev.inner.com",
"etcd02-dev.inner.com",
"etcd03-dev.inner.com",
"k8sdev001",
"k8sdev002",
"k8sdev003"
],
"key":
{
"algo": "rsa",
"size": 2048
},
"names":
[
{
"C": "CN",
"ST": "GuangDong",
"L": "GuangDong",
"O": "k8s",
"OU": "System"
}
]
}
EOF
# 创建 CA 证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
# 创建 etcd 证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
# 此时执行 ls -al |grep -v json 可以看到如下文件情况
-rw-r--r-- 1 root root 1005 Mar 23 16:06 ca.csr
-rw------- 1 root root 1675 Mar 23 16:06 ca-key.pem
-rw-rw-r-- 1 root root 1322 Mar 23 16:06 ca.pem
-rw-r--r-- 1 root root 1188 Mar 23 16:06 kubernetes.csr
-rw------- 1 root root 1679 Mar 23 16:06 kubernetes-key.pem
-rw-rw-r-- 1 root root 1521 Mar 23 16:06 kubernetes.pem
🔑上面生成的文件应该复制到所有机器,一个是构建
etcd
集群需要,再者后续如果需要构建k8s
集群,kubeadm
也需要用到它们!
进行 etcd 配置
关于 etcd
的配置内容本篇文章不多讲解,大家可以先自行了解!
下面的配置着重关注几点:
name
的配置需要每个服务器设置单独的名字,此处我用了etcd-dev-${num}
listen-client-urls
,listen-peer-urls
,initial-advertise-peer-urls
替换成节点的 IPadvertise-client-urls
修改成你需要对外暴露的地址,如果需要内外网都设置可以参考我的设置进行调整initial-cluster
是集群的所有机器地址, 格式为${name}=https://${your_ip}:2380
,多个机器用英文逗号分隔initial-cluster-token
按照您的需要调整即可etcd
使用的默认端口号2379
和2380
您也可以根据实际需要调整,调整的话防火墙策略也要进行变更
cat > /etc/etcd/etcd-config.yaml <<EOF
# 请注意,每台服务器需要控制name是不一样的
name: etcd-dev-1
data-dir: /data/database/etcd
listen-client-urls: https://192.168.3.35:2379
listen-peer-urls: https://192.168.3.35:2380
initial-advertise-peer-urls: https://192.168.3.35:2380
advertise-client-urls: https://192.168.3.35:2379,https://10.12.3.40:2379
initial-cluster: etcd-dev-1=https://192.168.3.35:2380,etcd-dev-2=https://192.168.3.34:2380,etcd-dev-3=https://192.168.3.33:2380
# 请按需调整 initial-cluster-token
initial-cluster-token: etcd-dev-cluster
initial-cluster-state: new
client-transport-security:
cert-file: /etc/etcd/etcd-certs/kubernetes.pem
key-file: /etc/etcd/etcd-certs/kubernetes-key.pem
client-cert-auth: true
trusted-ca-file: /etc/etcd/etcd-certs/ca.pem
peer-transport-security:
cert-file: /etc/etcd/etcd-certs/kubernetes.pem
key-file: /etc/etcd/etcd-certs/kubernetes-key.pem
client-cert-auth: true
trusted-ca-file: /etc/etcd/etcd-certs/ca.pem
auto-compaction-mode: "periodic"
auto-compaction-retention: "24h"
EOF
🎀 别忘了设置文件权限
chown etcd:etcd /etc/etcd/etcd-config.yaml
提前放行防火墙策略
博主此处放行的是内外部的网段,因为本身博主是要将这个集群共享给不同团队使用!
如果您搭建的集群是团队内自使用的请自行定义放行范围规则!
另外,无论是防火墙还是下面的启动服务操作,都需要多台机器进行处理,请做好自检!
iptables -A INPUT -s 10.12.3.0/24 -p tcp -i eth0 -m multiport --dports 2379:2380 -j ACCEPT
iptables -A INPUT -s 192.168.3.0/24 -p tcp -i eth0 -m multiport --dports 2379:2380 -j ACCEPT
启动集群
- 创建或者调整服务文件
vim /usr/lib/systemd/system/etcd.service
,参考如下内容
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
WorkingDirectory=/data/database/etcd
EnvironmentFile=-/etc/etcd/etcd.conf
User=etcd
ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/bin/etcd --config-file /etc/etcd/etcd-config.yaml"
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
- 设置开机启动并启动服务
# 重载上面变更的 service 配置
systemctl daemon-reload
# 设置 etcd 服务开机启动
systemctl enable etcd
# 启动 etcd
systemctl start etcd
# 检查服务是否正常运行
systemctl status etcd
📌 如果您碰到无法解决的问题,欢迎在评论区留言,我这边会根据自己的经验看下是否能为您提供一些帮助!
验证集群
🎊 恭喜您,到了这一步基本说明您前面搭建都是比较顺利的,接下来就是最重要的,验证集群是否顺利搭建完成
# 登录到任意一台 etcd 节点, 执行 etcdctl 命令,获取 etcd 集群的状态信息
etcdctl --endpoints=https://192.168.3.33:2379,https://192.168.3.34:2379,https://192.168.3.35:2379 --ca-file=/etc/etcd/etcd-certs/ca.pem --cert-file=/etc/etcd/etcd-certs/kubernetes.pem --key-file=/etc/etcd/etcd-certs/kubernetes-key.pem cluster-health
# 如果您也开启了外部访问,别忘了也进行简单的验证哦
etcdctl --endpoints=https://10.12.3.40:2379,https://10.12.3.41:2379,https://10.12.3.42:2379 --ca-file=/etc/etcd/etcd-certs/ca.pem --cert-file=/etc/etcd/etcd-certs/kubernetes.pem --key-file=/etc/etcd/etcd-certs/kubernetes-key.pem cluster-health
# 下面是更为美化的查看方式
ETCDCTL_API=3 etcdctl --endpoints=https://192.168.3.33:2379,https://192.168.3.34:2379,https://192.168.3.35:2379 --cacert=/etc/etcd/etcd-certs/ca.pem --cert=/etc/etcd/etcd-certs/kubernetes.pem --key=/etc/etcd/etcd-certs/kubernetes-key.pem endpoint health --write-out=table
# 如果您能看到类似如下的输出,恭喜您已经成功搭建好集群了
https://192.168.3.34:2379 is healthy: successfully committed proposal: took = 3.457399ms
https://192.168.3.35:2379 is healthy: successfully committed proposal: took = 4.456716ms
https://192.168.3.33:2379 is healthy: successfully committed proposal: took = 1.745809ms
etcd
也提供了基于 用户名和密码的身份认证机制 ,可以用来替代或补充TLS
证书认证机制。
您可以根据您的实际需要来选择用TLS
模式 还是 身份认证模式 来构建集群,但是后者安全性较弱一些!