一、Etcd 简介
Etcd 是一种分布式 kv 存储设施, 他具有一定的一致性,高性能,高可用的方案. 类似的 zookeeper, 但没有 zookeeper 那么重型,功能也没有覆盖那么多. 简单直接的应用就是配置中心
节点信息:
name | host |
node0 | 192.168.0.240 |
node1 | 192.168.0.241 |
node3 | 192.168.0.242 |
二、准备工作
1.关闭并停用防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service
2.永久关闭SELinux
vim /etc/selinux/config
SELINUX=disabled
3.同步集群系统时间
yum -y install ntp
ntpdate cn.ntp.org.cn
4.重启机器
reboot
三、TLS密钥和证书
1.安装go语言组件
cd /usr/local/src
wget http://redirector.gvt1.com/edgedl/go/go1.9.2.linux-amd64.tar.gz
tar -xvf go1.9.2.linux-amd64.tar.gz -C /usr/local
2.配置go环境
cat >> /etc/profile << EOF
#go的安装路径
export GOROOT=/usr/local/go
#go安装的工具路径
export GOPATH=/opt/go
export PATH=$GOROOT/bin:$PATH
EOF
source /etc/profile
3.安装cfssl
将会用使用cfssl生成所需要的私钥和证书
go get -u github.com/cloudflare/cfssl/cmd/...
会在$GOPATH/bin下安装cfssl, cfssjosn, mkbundle等工具。
创建CA证书和私钥,准备为etcd和其它组件办法证书和签名
创建ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"aspire": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
ca-config.json中可以定义多个profile,分别设置不同的expiry和usages等参数。如上面的ca-config.json中定义了名称为aspire的profile,这个profile的expiry 87600h为10年,useages中:
- signing表示此CA证书可以用于签名其他证书,ca.pem中的CA=TRUE
- server auth表示TLS Server Authentication
- client auth表示TLS Client Authentication
创建CA证书签名请求配置ca-csr.json
{
"CN": "aspire",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "aspire",
"OU": "cloudnative"
}
]
}
生成CA证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
ls
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
生成etcd证书和私钥
创建etcd证书签名请求配置etcd-csr.json
{
"CN": "aspire.etcd",
"hosts": [
"127.0.0.1",
"192.168.0.240",
"192.168.0.241",
"192.168.0.242",
"node0",
"node1",
"node2"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "aspire.etcd",
"OU": "Operation and maintenance center"
}
]
}
该”hosts”是可以使用该证书域名列表。‘CN’,kube-apiserver从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
该”names”值实际上是名称对象的列表。每个名称对象应至少包含一个“C”,“L”,“O”,“OU”或“ST”值(或这些的任意组合)。这些值是:
- “C”:国家
- “L”:地区或城市(如城市或城镇名称)
- “O”:组织 Organization,kube-apiserver从证书中提取该字段作为请求用户所属的组 (Group);
- “OU”:组织单位,如负责拥有密钥的部门; 它也可以用于“做生意”(DBS)的名称
- “ST”:州或省
下面生成etcd的证书和私钥:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=aspire etcd-csr.json | cfssljson -bare etcd
对生成的证书可以使用cfssl或openssl查看
$ cfssl-certinfo -cert etcd.pem
{
"subject": {
...
"cloudnative",
"aspire"
]
},
"serial_number": "555738010691550377350124675225187029254417657480",
"sans": [
"127.0.0.1",
"192.168.0.240",
"192.168.0.241",
"192.168.0.242",
"node0",
"node1",
"node2"
],
"not_before": "2018-12-18T06:57:00Z",
"not_after": "2028-12-16T06:57:00Z",
"sigalg": "SHA256WithRSA",
"authority_key_id": "DB:5D:58:25:31:D5:2A:D8:DB:C1:EF:C4:68:B4:B0:13:FA:6B:42:C3",
"subject_key_id": "6D:9B:6E:6A:F8:40:4D:4C:03:A4:0F:05:58:E1:9A:72:2E:8E:AB:58",
"pem": "-----BEGIN CERTIFICATE-----\nMIIETjCCAzagAwIBAgIUYVgnfkNJEfm75Tye3fynwTrvrogwDQYJKoZIhvcNAQEL\nBQAwaTELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaUppbmcxEDA...
"
}
将生成的CA证书ca.pem, etcd秘钥etcd-key.pem, etcd证书etcd.pem拷贝到各节点的/etc/etcd/ssl目录中
四、ETCD 安装与配置
1. 安装ETCD:
yum -y install etcd (由于是rpm包所以可以用remove卸载)
2. 配置准备:
#创建数据与日志文件目录
mkdir -p /data/etcd/{data,logs}
#创建用户与目录授权
useradd -s /sbin/nologin -M -U etcd && chown -R etcd:etcd /data/etcd/
3. 配置etcd.service :
在每个节点上创建etcd的systemd unit文件/usr/lib/systemd/system/etcd.service,注意替换ETCD_NAME和INTERNAL_IP变量的值:
export ETCD_NAME=node1
export INTERNAL_IP=192.168.0.240
cat > /usr/lib/systemd/system/etcd.service <<EOF
[Unit]
Description=etcd server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd
EnvironmentFile=-/etc/etcd/etcd.conf
ExecStart=/usr/bin/etcd \
--name ${ETCD_NAME} \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--peer-cert-file=/etc/etcd/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \
--trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
--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-1 \
--initial-cluster node0=https://192.168.0.240:2380,node1=https://192.168.0.241:2380,node2=https://192.168.0.242:2380 \
--initial-cluster-state new \
--data-dir=/data/etcd/
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
上面在启动参数中指定了etcd的工作目录和数据目录是/var/lib/etcd
- –cert-file和–key-file分别指定etcd的公钥证书和私钥
- –peer-cert-file和–peer-key-file分别指定了etcd的Peers通信的公钥证书和私钥。
- –trusted-ca-file指定了客户端的CA证书
- –peer-trusted-ca-file指定了Peers的CA证书
- –initial-cluster-state new表示这是新初始化集群,–name指定的参数值必须在–initial-cluster中
etcd 启动
在各节点启动etcd
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
systemctl status etcd
检查集群是否健康
etcdctl \
--ca-file=/etc/etcd/ssl/ca.pem \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--endpoints=https://node0:2379,https://node1:2379,https://node2:2379 \
cluster-health
2019-04-24 19:53:40.545148 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
2019-04-24 19:53:40.546127 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
member 4f2f99d70000fc19 is healthy: got healthy result from https://192.168.0.240:2379
member 99a756f799eb4163 is healthy: got healthy result from https://192.168.0.241:2379
member a9aff19397de2e4e is healthy: got healthy result from https://192.168.0.242:2379
cluster is healthy
增减成员节点
1.新增节点:
新增节点(例如192.168.0.243)
在集群任意节点输入:
etcdctl member add http://192.168.0.243:2380
命令行返回:
added member 9bf1b35fc7761a23 to cluster
ETCD_NAME="node3"
ETCD_INITIAL_CLUSTER="node0=http://192.168.0.240:2380,node1=http://192.168.0.241,node2=http://192.168.0.242:2380,node3=http://192.168.0.243:2380"
ETCD_INITIAL_CLUSTER_STATE=existing
其中ETCD_INITIAL_CLUSTER是最为重要的信息,记录了集群成员。
2.删除节点:
删除节点的etcd
etcdctl member remove 节点ID
3.备份数据:
etcdctl backup --data-dir /data/etcd/data/ --backup-dir /data/backup/etcd
五、ETCD 操作
etcd 在键的组织上采用了层次化的空间结构(类似于文件系统中目录的概念),用户指定的键可以为单独的名字,如 testkey
,此时实际上放在根目录 /
下面,也可以为指定目录结构,如 cluster1/node2/testkey
,则将创建相应的目录结构。
注:CRUD 即 Create, Read, Update, Delete,是符合 REST 风格的一套 API 操作。
set
指定某个键的值。例如
➜ ~ etcdctl set /testdir/testkey “Hello world” Hello world |
支持的选项包括:
–ttl ‘0’ 该键值的超时时间(单位为秒),不配置(默认为 0)则永不超时 –swap-with-value value 若该键现在的值是 value,则进行设置操作 –swap-with-index ‘0’ 若该键现在的索引值是指定索引,则进行设置操作 |
get
获取指定键的值。例如
➜ ~ etcdctl get /testdir/testkey Hello world |
当键不存在时,则会报错。例如
➜ ~ etcdctl get /testdir/testkey2 Error: 100: Key not found (/testdir/testkey2) [18] |
支持的选项为
–sort 对结果进行排序 –consistent 将请求发给主节点,保证获取内容的一致性 |
update
当键存在时,更新值内容。例如
➜ ~ etcdctl update /testdir/testkey “Hello” Hello |
当键不存在时,则会报错。例如
➜ ~ etcdctl update /testdir/testkey2 “Hello” Error: 100: Key not found (/testdir/testkey2) [19] |
支持的选项为
–ttl ‘0’ 超时时间(单位为秒),不配置(默认为 0)则永不超时 |
rm
删除某个键值。例如
➜ ~ etcdctl rm /testdir/testkey PrevNode.Value: Hello |
当键不存在时,则会报错。例如
➜ ~ etcdctl rm /testdir/testkey Error: 100: Key not found (/testdir/testkey) [20] |
支持的选项为
–dir 如果键是个空目录或者键值对则删除 –recursive 删除目录和所有子键 –with-value 检查现有的值是否匹配 –with-index ‘0’ 检查现有的 index 是否匹配 |
mk
如果给定的键不存在,则创建一个新的键值。例如
➜ ~ etcdctl mk /testdir/testkey “Hello world” Hello world |
当键存在的时候,执行该命令会报错,例如
➜ ~ etcdctl mk /testdir/testkey “Hello world” Error: 105: Key already exists (/testdir/testkey) [21] |
支持的选项为
–ttl ‘0’ 超时时间(单位为秒),不配置(默认为 0)则永不超时 |
mkdir
如果给定的键目录不存在,则创建一个新的键目录。例如
➜ ~ etcdctl mkdir testdir2 |
当键目录存在的时候,执行该命令会报错,例如
➜ ~ etcdctl mkdir testdir2 Error: 105: Key already exists (/testdir2) [22] |
支持的选项为
–ttl ‘0’ 超时时间(单位为秒),不配置(默认为 0)则永不超时 |
setdir
创建一个键目录,无论存在与否。
支持的选项为
–ttl ‘0’ 超时时间(单位为秒),不配置(默认为 0)则永不超时 |
updatedir
更新一个已经存在的目录。 支持的选项为
–ttl ‘0’ 超时时间(单位为秒),不配置(默认为 0)则永不超时 |
rmdir
删除一个空目录,或者键值对。
➜ ~ etcdctl setdir dir1 ➜ ~ etcdctl rmdir dir1 |
若目录不空,会报错
➜ ~ etcdctl set /dir/testkey hi hi ➜ ~ etcdctl rmdir /dir Error: 108: Directory not empty (/dir) [29] |
ls
列出目录(默认为根目录)下的键或者子目录,默认不显示子目录中内容。
例如
➜ ~ etcdctl ls /testdir /testdir2 /dir ➜ ~ etcdctl ls dir /dir/testkey |
支持的选项包括
–sort 将输出结果排序 –recursive 如果目录下有子目录,则递归输出其中的内容 -p 对于输出为目录,在最后添加 `/` 进行区分 |
六、ETCD 管理
backup
备份 etcd 的
支持的选项包括
–data-dir etcd 的数据目录 –backup-dir 备份到指定路径 |
watch
监测一个键值的变化,一旦键值发生更新,就会输出最新的值并退出。
例如,用户更新 testkey 键值为 Hello watch。
➜ ~ etcdctl get /testdir/testkey Hello world ➜ ~ etcdctl set /testdir/testkey “Hello watch” Hello watch |
➜ ~ etcdctl watch testdir/testkey Hello watch |
支持的选项包括
–forever 一直监测,直到用户按 `CTRL+C` 退出 –after-index ‘0’ 在指定 index 之前一直监测 –recursive 返回所有的键值和子键值 |
exec-watch
监测一个键值的变化,一旦键值发生更新,就执行给定命令。
例如,用户更新 tes
➜ ~ etcdctl exec-watch testkey — sh -c ‘ls’ default.etcd Documentation etcd etcdctl etcd-migrate README-etcdctl.md README.md |
支持的选项包括
–after-index ‘0’ 在指定 index 之前一直监测 –recursive 返回所有的键值和子键值 |
member
通过 list、add、remove 命令列出、添加、删除 etcd 实例到 etcd 集群中。
例如本地启动一个 etcd 服务实例后,可以用如下命令进行查看。
$ etcdctl member list ce2a822cea30bfca: name=default peerURLs=http://localhost:2380,http://localhost:7001 clientURLs=http://localhost:2379,http://localhost:4001 |
命令选项
--debug 输出 cURL 命令,显示执行命令的时候发起的请求
--no-sync 发出请求之前不同步集群信息
--output, -o 'simple' 输出内容的格式 (simple 为原始信息,json 为进行json格式解码,易读性好一些)
--peers, -C 指定集群中的同伴信息,用逗号隔开 (默认为: "127.0.0.1:4001")
--cert-file HTTPS 下客户端使用的 SSL 证书文件
--key-file HTTPS 下客户端使用的 SSL 密钥文件
--ca-file 服务端使用 HTTPS 时,使用 CA 文件进行验证
--help, -h 显示帮助命令信息
--version, -v 打印版本信息
七、ETCD 总结
ETCD集群的操作分两个阶段,即启动与运行阶段,启动阶段的集群有3种配置方式,
- 静态配置
- etcd自发现模式
- DNS自发现模式
本文采用的是静态配置,etcd自发现模式与静态配置的区别在于静态模式预先知道所有节点的ip信息,而etcd自发现则不用,
配置方法与静态配置类似,仅仅将启动脚本 etcd.service 中–initial-cluster参数去掉,新增:
--discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de\
其中,discovery参数的获取方法:
curl https://discovery.etcd.io/new?size=3
返回
https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de
两种启动方法的运行阶段操作基本一致。