k8s高可用环境部署3(Etcd)
前言环境和部分软件已经配置好了,接着要部署一个Etcd集群。Etcd 通常是和master部署在一起,也有人会将 etcd独立于 k8s集群之外,以便于更好地扩展etcd集群。而此次是部署在3个master上。下面是关于Etcd的一些简单介绍:Etcd节点数:etcd 是基于raft算法的分布式键值数据库,在做决策时需要超半数节点的投票,所以 etcd集群 一般推荐奇数节点(3,5,7);etcd
前言
环境和部分软件已经配置好了,接着要部署一个Etcd集群。Etcd 通常是和master部署在一起,也有人会将 etcd独立于 k8s集群之外,以便于更好地扩展etcd集群。而此次是部署在3个master上。
下面是关于Etcd的一些问题及答案:
Etcd节点数:
etcd 是基于raft算法的分布式键值数据库,在做决策时需要超半数节点的投票,所以 etcd集群 一般推荐奇数节点(3,5,7);etcd是高可用的,3节点etcd集群,最大容忍1台机器宕机。根据网上的资料:设置偶数节点也是可以的,但是会拉低写入速度。节点数越多,性能越差。
限制Etcd性能的因素:
单机的容量限制,内存和磁盘(这基本上是大部分服务的主要限制因素之一。可使用ionice调高etcd进程的IO优先级;部署etcd集群使用性能较高,内存较大的服务器,如果是云服务器可选择高性能云盘)
ionice -c2 -n0 -p `pgrep etcd`
Etcd配置的容量上限(Etcd默认配置的容量上限较小。当ETCD的存储使用超过了空间配额,ETCD 将发起集群范围的警告,并使集群进入维护模式,仅接收键的读取和删除,从而影响平台的正常运行。因此需要部署时调整ETCD 容量上限)
网络开销(每次 Raft 操作都需要所有节点参与。每一次写操作需要集群中大多数节点将日志落盘成功后,Leader节点才能修改内部状态,并将结果返回给客户端。频繁的交互,对网络的要求较高。因此通常会将 etcd 集群规划在一个网络环境中(同地域/同机房),并且使用tc提高带宽和优先级)
tc qdisc add dev eth0 root handle 1: prio bands 3
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip sport 2380 0xffff flowid 1:1
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip dport 2380 0xffff flowid 1:1
tc filter add dev eth0 parent 1: protocol ip prio 2 u32 match ip sport 2739 0xffff flowid 1:1
tc filter add dev eth0 parent 1: protocol ip prio 2 u32 match ip dport 2739 0xffff flowid 1:1
ETCD部署
本次使用的源码包部署一个外部的ETCD集群
生成证书
以下操作在 etcd1(即master01)机器执行
<1>下载证书生成工具
curl -o /usr/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
curl -o /usr/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
curl -o /usr/bin/cfssl-certinfo https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x /usr/bin/cfssl*
<2>创建证书etcd目录
mkdir -p /etc/kubernetes/pki/etcd
cd /etc/kubernetes/pki/etcd
根据需求创建目录,实际建议etcd证书放到其他位置(当证书放到/etc/kubernetes时,虽然便于统一管理,但kubeadm reset后,etcd的证书也会丢失。如不想重新配置etcd,建议证书放到其他位置)
先进入目录再生成证书,否则证书比较散乱
<3>创建 CA 配置文件(ca-config.json)
cat >ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"etcd": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "876000h"
}
}
}
}
EOF
or
使用命令生成,然后对其进行修改
cfssl print-defaults config > ca-config.json
备注:
"ca-config.json": 可以定义多个profiles,分别指定不同的过期时间、使用场景等参数
"signing": 表示该证书可用于签名其它证书
"expiry": 表示证书的有效时间(876000h=100年),根据需求配置
"key encipherment":密钥加密
"server auth": 表示client可以用该 CA 对server提供的证书进行验证
"client auth": 表示server可以用该CA对client提供的证书进行验证
<4>创建 CA 证书签名请求(ca-csr.json)
cat >ca-csr.json <<EOF
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "shanghai",
"L": "shanghai",
"O": "etcd",
"OU": "System"
}
]
}
EOF
or
使用命令生成,然后对其进行修改
cfssl print-defaults csr > ca-csr.json
备注:
"CN": etcd会从证书中提取该字段作为请求的用户名,根据需求起名字
"O": etcd 从证书中提取该字段作为请求用户所属的组
"C": 国家编码
"ST": 省份
"L": 市/区
"O": 公司名称
"OU": 部门名称
随意填即可
<5>生成 CA 证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
生成下面3个文件
ca.pem 根证书公钥文件,用于签发后续其他的证书文件
ca-key.pem 根证书私钥文件
ca.csr 证书签名请求,用于交叉签名或重新签名
<6>以上操作可写脚本,简便一些
简洁型ca脚本:
#!/bin/bash
cat >ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"etcd": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "876000h"
}
}
}
}
EOF
cat >ca-csr.json <<EOF
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "shanghai",
"L": "shanghai",
"O": "etcd",
"OU": "System"
}
]
}
EOF
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
<7>创建etcd的TLS认证证书
#创建 etcd证书签名请求(etcd-csr.json)
cat > etcd-csr.json <<EOF
{
"CN": "etcd",
"hosts": [
"192.168.1.1",
"192.168.1.2",
"192.168.1.3",
"k8s-master01",
"k8s-master02",
"k8s-master03"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "shanghai",
"L": "shanghai",
"O": "etcd",
"OU": "System"
}
]
}
EOF
备注:
"hosts": 指定授权使用该证书的IP和域名列表(即指定了etcd集群各个节点的IP/域名)
<8>生成 etcd证书和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd etcd-csr.json | cfssljson -bare etcd
生成下面3个文件
etcd.csr
etcd.pem
etcd-key.pem
<9>etcd证书拷贝
本次etcd部署在master上,且由于在初始化阶段,master间进行了免密认证,直接推送即可。
重点在于将前面生成的证书拷贝到其他节点。
rsync -aP /etc/kubernetes root@k8s-master02:/etc/
rsync -aP /etc/kubernetes root@k8s-master03:/etc/
<10>以上操作可写脚本,简便一些
简洁型etcd证书脚本:
#!/bin/bash
cat > etcd-csr.json <<EOF
{
"CN": "etcd",
"hosts": [
"192.168.1.1",
"192.168.1.2",
"192.168.1.3",
"k8s-master01",
"k8s-master02",
"k8s-master03"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "shanghai",
"L": "shanghai",
"O": "etcd",
"OU": "System"
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd etcd-csr.json | cfssljson -bare etcd
rsync -aP /etc/kubernetes root@k8s-master02:/etc/
rsync -aP /etc/kubernetes root@k8s-master03:/etc/
Etcd安装配置
以下操作在各个etcd节点,修改参数后再执行
<1>创建etcd数据目录
(统一的数据目录,可便于管理)
mkdir -p /data/etcd
chmod -R 777 /data/etcd
ln -s /data/etcd /var/lib/etcd
<2>下载etcd源码包
版本建议选择3.4及其以上,3.4存储容量做了提升,降低了读写延迟;且3.3以下等版本存在数据不一致的bug
#选择合适版本和方式下载即可
export ETCD_VERSION=v3.4.4
curl -sSL https://github.com/coreos/etcd/releases/download/${ETCD_VERSION}/etcd-${ETCD_VERSION}-linux-amd64.tar.gz | tar -xzv --strip-components=1 -C /usr/local/bin/
or
wget https://github.com/coreos/etcd/releases/download/v3.4.4/etcd-v3.4.4-linux-amd64.tar.gz
<3>创建etcd环境配置文件
ETCD3.4版本会自动读取环境变量的参数,所以EnvironmentFile文件中有的参数,不需要再次在ExecStart启动参数中添加
#!/bin/bash
#PEER_NAME指定本节点的主机名称/域名,
#PRIVATE_IP指定本节点的IP(用于后面配置文件的生成)
#ETCD_CLUSTER群集列表,是所有节点信息(内容格式: 各节点名称=https://ip:端口 名称任意但要有标识性)
#ETCD_INITIAL_CLUSTER_TOKEN为该etcd集群Token,同一集群token一致
#需将此操作在每个etcd节点执行,前2个变量执行时需分别配置为 当前节点的 信息,意思是如果是
cat > /etc/etcd.env <<EOF
PEER_NAME=k8s-master01
PRIVATE_IP=192.168.1.1
ETCD_CLUSTER="k8s-master01=https://192.168.1.1:2380,k8s-master02=https://192.168.1.2:2380,k8s-master03=https://192.168.1.3:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1"
EOF
cat > /etc/systemd/system/etcd.service <<EOF
[Unit]
Description=etcd
Documentation=https://github.com/coreos/etcd
Conflicts=etcd.service
Conflicts=etcd2.service
[Service]
EnvironmentFile=/etc/etcd.env
Type=notify
Restart=always
RestartSec=5s
LimitNOFILE=65536
TimeoutStartSec=0
ExecStart=/usr/local/bin/etcd --name ${PEER_NAME} \
--data-dir /var/lib/etcd \
--listen-client-urls https://${PRIVATE_IP}:2379 \
--advertise-client-urls https://${PRIVATE_IP}:2379 \
--listen-peer-urls https://${PRIVATE_IP}:2380 \
--initial-advertise-peer-urls https://${PRIVATE_IP}:2380 \
--cert-file=/etc/kubernetes/pki/etcd/etcd.pem \
--key-file=/etc/kubernetes/pki/etcd/etcd-key.pem \
--client-cert-auth \
--trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \
--peer-cert-file=/etc/kubernetes/pki/etcd/etcd.pem \
--peer-key-file=/etc/kubernetes/pki/etcd/etcd-key.pem \
--peer-client-cert-auth \
--peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \
--initial-cluster ${ETCD_CLUSTER} \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster-state new
[Install]
WantedBy=multi-user.target
EOF
需注意内容:
2379是提供给外部端口,2380是内部集群通讯端口
EnvironmentFile 指定环境变量文件
ExecStart 指定启动文件
--data-dir 指定数据目录
--listen-client-urls 对外提供服务的地址
--listen-peer-urls 和成员之间通信的地址
--initial-cluster-token 创建集群的 token,这个值每个集群保持唯一
--client-cert-auth 启用客户端证书验证
--peer-client-cert-auth 启用对等客户端证书验证
--initial-cluster-state 集群状态,默认为new(初始时建议设置为new。当一个节点故障后恢复时,该节点调整为existing,etcd将尝试使其加入现有群集)
下列参数皆为指定密钥文件,就不具体介绍了
--cert-file
--key-file
--client-cert-auth
--trusted-ca-file
--peer-cert-file
--peer-key-file
--peer-client-cert-auth
--peer-trusted-ca-file
调优
(1s=1000ms)
下列参数可写入配置文件,也可用命令调整
当开启证书验证,如果需要使用命令调整参数,需要加上证书,否则无法执行
--heartbeat-interval 心跳间隔的时间(以毫秒为单位)默认100
应该被设置为节点之间网络往返时间,节点网络延迟较高时,可适当调高(跨机房/地域,通常最高为5s)
--election-timeout 选举超时的时间(以毫秒为单位)默认1000
不均匀的网络性能或者常规的网络延迟和丢失,会引起多次网络重试,延迟过大可调高超时时间最高值应该是50s
调参命令:etcd --heartbeat-interval=100 --election-timeout=500
--max-snapshots 要保留的最大快照文件数(0表示不受限制)默认5
--snapshot-count 触发快照到磁盘的已提交事务数。默认100000
当参数累积到一定的数量时,Etcd 才会创建快照文件。如果 Etcd的内存使用和磁盘使用过高,可调低快照触发的阈值5000
调参命令:etcd --snapshot-count=5000
--auto-compaction-retention 自动压缩,默认为0不开启(默认小时为单位)。etcd会存储多版本数据,随着写入的主键增加,历史版本将会越来越多,并且默认不清理。可根据需求,设置压缩时间间隔。
调参命令:etcd --auto-compaction-retention=1
--max-request-bytes 服务器将接受的最大客户端请求大小(字节)默认1572864,1.5M
官方推荐的是10M,建议根据需求自行调整
--quota-backend-bytes 当后端db数据大小超过给定配额时,引发警报并不允许写入,空间释放足够的空间之后,警告可以被解除,而集群将恢复正常运作,默认是2G
官方推荐是8G配置,也可根据需求配置100G,并不是越大越好,key存储越多性能越差
调参命令:etcd --max-request-bytes=$((32*1024*1024)) --quota-backend-bytes=$((8*1024*1024*1024))
<5>启动etcd集群
systemctl daemon-reload
systemctl start etcd
systemctl enable etcd
systemctl status etcd -l
如果启动失败,检测一下当前节点是否存在etcd证书
<6>配置脚本,获取etcd集群服务的信息
cat etcd_healthy.sh
#!/bin/bash
HOST1=192.168.1.1
HOST2=192.168.1.2
HOST3=192.168.1.3
ENDPOINTS=$HOST1:2379,$HOST2:2379,$HOST3:2379
#因为开启了证书验证,因此执行命令需加上证书
KEY="--cacert=/etc/kubernetes/pki/etcd/ca.pem \
--cert=/etc/kubernetes/pki/etcd/etcd.pem \
--key=/etc/kubernetes/pki/etcd/etcd-key.pem"
#etcd集群健康信息
etcdctl --endpoints=$ENDPOINTS $KEY endpoint health
#etcd集群状态信息
etcdctl --endpoints=$ENDPOINTS $KEY --write-out=table endpoint status
#etcd集群成员信息
etcdctl --endpoints=$ENDPOINTS $KEY member list -w table
以下为实际环境执行时得到的,因此ip与文档不一致
172.22.57.184:2379 is healthy: successfully committed proposal: took = 10.085925ms
172.22.57.185:2379 is healthy: successfully committed proposal: took = 10.220026ms
172.22.57.187:2379 is healthy: successfully committed proposal: took = 11.350372ms
+--------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+--------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 172.22.57.184:2379 | 4fdbc756dda5ffbb | 3.4.4 | 1.6 MB | false | false | 94 | 289210 | 289210 | |
| 172.22.57.187:2379 | c6c78a8f420b5599 | 3.4.4 | 1.6 MB | true | false | 94 | 289210 | 289210 | |
| 172.22.57.185:2379 | 3067cb577abc7d54 | 3.4.4 | 1.6 MB | false | false | 94 | 289210 | 289210 | |
+--------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
+------------------+---------+---------+----------------------------+----------------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+---------+---------+----------------------------+----------------------------+------------+
| 3067cb577abc7d54 | started | master3 | https://172.22.57.185:2380 | https://172.22.57.185:2379 | false |
| 4fdbc756dda5ffbb | started | master1 | https://172.22.57.184:2380 | https://172.22.57.184:2379 | false |
| c6c78a8f420b5599 | started | master2 | https://172.22.57.187:2380 | https://172.22.57.187:2379 | false |
+------------------+---------+---------+----------------------------+----------------------------+------------+
<7>配置脚本,有需要时释放空间
cat etcd_clean.sh
#!/bin/bash
#说明:
#由于配置了endpoints,在任意节点执行一次即可清理ETCD各节点空间
#如需清理单个节点,不加endpoints即可
#碎片整理会阻塞对etcd的读写操作,数据较大时defrag建议逐台进行
HOST1=192.168.1.1
HOST2=192.168.1.2
HOST3=192.168.1.3
ENDPOINTS=$HOST1:2379,$HOST2:2379,$HOST3:2379
#因为开启了证书验证,因此执行命令需加上证书
KEY="--cacert=/etc/kubernetes/pki/etcd/ca.pem \
--cert=/etc/kubernetes/pki/etcd/etcd.pem \
--key=/etc/kubernetes/pki/etcd/etcd-key.pem"
#获取当前历史修订版本
rev=$(ETCDCTL_API=3 etcdctl --endpoints=$ENDPOINTS $KEY endpoint status --write-out="json" | egrep -o '"revision":[0-9]*' | egrep -o '[0-9].*')
#压缩到指定的修订版本
##数据压缩并不是清理现有数据,只是对给定版本之前的历史版本进行清理,清理后数据的历史版本将不能访问,不会影响现有最新数据的访问压缩
#示例:ETCDCTL_API=3 etcdctl --endpoints=${ENDPOINTS} ${KEY} compact 5
ETCDCTL_API=3 etcdctl --endpoints=${ENDPOINTS} ${KEY} compact $rev
# 反碎片化(碎片整理,释放空间)
ETCDCTL_API=3 etcdctl --endpoints=${ENDPOINTS} ${KEY} defrag
# 解除警报
ETCDCTL_API=3 etcdctl --endpoints=${ENDPOINTS} ${KEY} alarm disarm
更多推荐
所有评论(0)