k8s 二进制部署 四 (etcd)

大番茄 2019年10月25日 371次浏览

v3.3.17

一、环境

etcd作为k8s的存储,以及数据交换, 重要性可想而知,线上一般5节点。

etcd 3.4版本不支持v2接口, 因为后面的flannel v0.11.0只能使用v2接口,所以使用 3.3.17 的版本。

二、准备

1、etcd参数介绍。

--initial-advertise-peer-urls           # 公布给其他节点可以连接的url, 这个只能与--initial-cluster-state里的本节点相同,不然无法启动。 生成集群对等成员列表。
--listen-peer-urls                      # 监听其他节点的url
--listen-client-urls                    # 监听客户端的url
--advertise-client-urls                 # 公布可以给客户端请求的url, 不要写类似127.0.0.1的私有地址。 生成响应客户端的成员列表,etcd客户端库解析url以连接集群。下面详细介绍。
--initial-cluster-token                 # 集群名称
--initial-cluster                       # 集群所有所有节点
--initial-cluster-state                 # 集群状态,  估计除了新节点要加入已存在的集群,其他都是new。 集群有3个节点,一个节点迟迟没有加入的情况下, 这个节点启动的时候也是new, 因为本身它就是集群中的节点。
# 客户端认证
--client-cert-auth                      # 启用客户端证书认证
--trusted-ca-file                       # 信任的客户端的ca证书,也就是用来验证客户端证书是否有效的ca证书。
# 客户端访问接口的https证书配置, 也就是2379端口的https证书。
--cert-file                             # 提供给客户端的https接口的证书。
--key-file
--client-crl-file                       # 指定证书注销文件,用于识别已被注销的客户端证书。
# 集群节点认证
--peer-client-cert-auth                 # 启用集群节点证书验证
--peer-trusted-ca-file                  # 证书验证其他节点的配置,  用来验证其他节点的ca证书。
# 集群节点访问的https配置的证书,也就是2380端口的https证书。
--peer-cert-file                        # 提供给集群节点的https接口的证书。
--peer-key-file

--data-dir                              # 数据文件

上面的client-crl-file 下面例子里没有: 就是指定客户端证书的注销文件。如:

--client-crl-file "/opt/etcd/cert/crl.pem"

crl.pem是CA里面的文件,私有CA刚初始化完就有,每次注销证书,文件都会变化,包含了所有注销证书的信息。 CA那里注销客户端证书以后,把crl.pem替换到这里,直接就可以生效,etcd不需要重启。

-----BEGIN X509 CRL-----
MIIC1zCBwAIBATANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJDTjELMAkGA1UE
CAwCQkoxCzAJBgNVBAcMAkJKMRIwEAYDVQQKDAlhdGVzdC5wdWIxDTALBgNVBAsM
BGV0Y2QxFTATBgNVBAMMDGNhLmF0ZXN0LnB1YjEbMBkGCSqGSIb3DQEJARYMb3BA
YXRlc3QucHViFw0yMDEyMTIwMzM3MDVaFw0yMTAxMTEwMzM3MDVaoA4wDDAKBgNV
HRQEAwIBADANBgkqhkiG9w0BAQsFAAOCAgEAVqmwB9IXp/9ugQb+Z0as9BQ8B167
24uV+HavdLOJACuTUh987MKQgOW75l63tT6Zyi2cW7C77hvAsIZcBNOSw5VQe5tw
vjnxbmsDoCVAMwRDvB/rcbziMOap6VcWp9jQ3gr2grxgW9qY0R0s4xp+JhDOoDku
EjBrCkqt/ql6zidnfpsR2wfSnVyutvpGVtdgXmys9mFbB85nYlZdzkD0oLTmmwqU
VerUpC3YcmH8+WVtX+UhHTcWzSirem6kYkl1koiSeazLCXxyuJ6UAdrfiinWlQLz
I/rdbjI78Xlgs0lB66QjbiQNVeS1XdQ5IaWo9MrfdoLXJSlYzO9a0DOEGCnGfG/Y
0HOaAKEoG2FOMmQMJrqTtAItFARPaAxoh8jUr6yoPNdsHM9ZFaz8sCd3a8HIII9J
UHVF1crTQqoJE5K2+3TV8WvaQinwdgBG1QA8BgNL+C7XCgs28KEJoz9R9sVDjxzG
M4lkQ/ivXs76L6c0XHwsX+J7LG0XTfFXJWZBqyEWqh0uaPqv+LwhOg/u5/5ikzqE
skZQd6w7cy7dFuXBOSffjsXwidpfTn/ZKy5l4q2FOIhXBAOtnG3ocfTUHA3+iy7a
Lcl+c+DL/yd//c3Ys9C9K3ZhHHfAd7JwyVe4Ze42wJBwehlPhlyRwhl3zoHzvcav
+XiudVd8mFVVGzA=
-----END X509 CRL-----

2、advertise-client-urls参数介绍:

原来一直对--listen-client-urls与--advertise-client-urls很疑惑。不明白为什么有监听地址,还要有通告给客户端的地址。
其实这个参数主要对类似V2版本etcdctl的客户端使用,如果使用http直接请求是没用的,V3版本的etcdctl客户端也没有用。下面细说:

v2版本的etcdctl或者类似的库在访问etcd的时候是两段试请求,
第一段请求 直接访问--listen-client-urls监听的地址,请求的内容是获取集群所有可访问的地址(/v2/members)。
image-8925ac55
返回的地址列表就是从--advertise-client-urls参数拿的。
image-c720cc3a

在命令请求的时候会从命令行指定的endpoint里选出一个地址执行members,如果不能访问则再访问下一个,那种情况就是会出现两条members请求。

第二段请求 使用返回的地址,再去获取真正的数据。选择一个地址执行数据操作,如果是127.0.0.1就跳过,如果节点访问不通就再尝试下一个节点。
image-ee09e934

也就是因为会跳过127.0.0.1, 所以--advertise-client-urls参数不用指定127.0.0.1的地址,指定了也没有问题。

直接执行http请求 则不会有两段式请求。
如下面这个启动方式是:
--listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://172.100.102.71:2379
以两段式请求的话应该是不通的, 因为返回的172.100.102.71:2379根本就没有监听。
image-cd3de278

但是直接http请求就可以了。
image-a61f08f1

v3版本的etcdctl
etcdctl工作模式就不一样了, member还是返回--advertise-client-urls制定的。
但是在访问的时候不会再二段请求了, 直接以--endpoints指定的参数访问了。
image-48a4f97f

image-3755b476

总结
--advertise-client-urls 参数主要还只是提供了members 接口的数据,提供集群中使用,v2 etcdctl也是使用了这个数据。

--listen-client-urls 真实监听的地址,真正提供请求的。客户端从members中选择的地址如果没有监听,也是访问不了的。 然后直接使用http请求的是这个参数的地址。

2、生成证书

使用工具生成etcd证书,使用证书认证的etcd。
这里使用同一套证书作为3节点etcd使用, 所以证书要包含3个节点的ip,要生成san扩展的证书。我这里还是使用脚本生成的证书,在CA那一篇有下载与使用,网上也有很多工具。
最终生成的证书需要有这一部分。三个接点ip包含进去,DNS那个在这里用不到,只是顺便添上了。
image-4fa2df3e

三、安装

从这里下载: https://github.com/etcd-io/etcd/releases
下载完成解压,只要里面的etcd, etcdctl 执行文件, 放到执行目录,这里是/usr/local/etcd/bin/下面。

[root@k8s-node1 etcd]# pwd
/usr/local/etcd
[root@k8s-node1 etcd]# ls
bin  conf  data  ssl
[root@k8s-node1 etcd]# tree
.
├── bin
│   ├── etcd
│   └── etcdctl
├── conf
│   └── etcd.conf
├── data
└── ssl
    ├── cacert.pem
    ├── etcd.crt
    └── etcd.key

4 directories, 6 files
[root@k8s-node1 etcd]#

创建Unit文件与配置文件

etcd支持从变量获取配置,但是有点担心变量被覆盖的问题,所以还是以命令行参数的方式启动。 一定注意etcd.service里面的\斜杠后面有没有空格,一不小心就容易搞出来。

[root@k8s-node1 etcd]# cat /lib/systemd/system/etcd.service
[Unit]
Description=Etcd server
After=network-online.target
Wants=network-online.target

[Service]
EnvironmentFile=/usr/local/etcd/conf/etcd.conf
Type=notify
ExecStart=/usr/local/etcd/bin/etcd \
--name ${YETCD_NAME} \
--initial-advertise-peer-urls ${YETCD_INITIAL_ADVERTISE_PEER_URLS} \
--listen-peer-urls ${YETCD_LISTEN_PEER_URLS} \
--listen-client-urls ${YETCD_LISTEN_CLIENT_URLS} \
--advertise-client-urls ${YETCD_ADVERTISE_CLIENT_URLS} \
--initial-cluster-token ${YETCD_INITIAL_CLUSTER_TOKEN} \
--initial-cluster ${YETCD_INITIAL_CLUSTER} \
--initial-cluster-state ${YETCD_CLUSTER_STATE} \
--client-cert-auth \
--trusted-ca-file ${YETCD_TRUSTED_CA_FILE} \
--cert-file ${YETCD_CERT_FILE} \
--key-file ${YETCD_KEY_FILE} \
--peer-client-cert-auth \
--peer-trusted-ca-file ${YETCD_PEER_TRUSTED_CA_FILE} \
--peer-cert-file ${YETCD_PEER_CERT_FILE} \
--peer-key-file ${YETCD_PEER_KEY_FILE} \
--data-dir ${YETCD_DATA_DIR}
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Unit中引用的变量文件, 因为etcd可以从变量获取配置的原因,导致不能使用ETCD开头的变量。

[root@k8s-master conf]# cat /usr/local/etcd/conf/etcd.conf  
YETCD_NAME="etcd01"  
YETCD_LISTEN_PEER_URLS="https://172.100.102.71:2380"  
YETCD_LISTEN_CLIENT_URLS="https://172.100.102.71:2379,https://127.0.0.1:2379"  
YETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.100.102.71:2380"  
YETCD_ADVERTISE_CLIENT_URLS="https://172.100.102.71:2379" 
YETCD_INITIAL_CLUSTER_TOKEN="k8s-etcd-cluster"  
YETCD_INITIAL_CLUSTER="etcd01=https://172.100.102.71:2380,etcd02=https://172.100.102.72:2380,etcd03=https://172.100.102.73:2380"  
YETCD_CLUSTER_STATE="new"  
YETCD_CLIENT_CERT_AUTH="true"  
YETCD_TRUSTED_CA_FILE="/usr/local/etcd/ssl/cacert.pem"  
YETCD_CERT_FILE="/usr/local/etcd/ssl/etcd.crt"  
YETCD_KEY_FILE="/usr/local/etcd/ssl/etcd.key"  
YETCD_PEER_CLIENT_CERT_AUTH="true"  
YETCD_PEER_TRUSTED_CA_FILE="/usr/local/etcd/ssl/cacert.pem"  
YETCD_PEER_CERT_FILE="/usr/local/etcd/ssl/etcd.crt"  
YETCD_PEER_KEY_FILE="/usr/local/etcd/ssl/etcd.key"  
YETCD_DATA_DIR="/usr/local/etcd/data/data.etcd"

把unit文件以及etcd目录传到其他节点并且修改配置文件。

如:

[root@k8s-node1 etcd]# scp /lib/systemd/system/etcd.service root@172.100.102.72:/lib/systemd/system/
[root@k8s-node1 etcd]# scp /lib/systemd/system/etcd.service root@172.100.102.73:/lib/systemd/system/
[root@k8s-node1 local]# scp -r etcd root@172.100.102.72:/usr/local/
[root@k8s-node1 local]# scp -r etcd root@172.100.102.73:/usr/local/
修改其他节点配置:

修改/usr/local/etcd/conf/etcd.conf里的这几个配置为相应的地址与集群节点名称。
node2:

YETCD_NAME="etcd02"  
YETCD_LISTEN_PEER_URLS="https://172.100.102.72:2380"  
YETCD_LISTEN_CLIENT_URLS="https://172.100.102.72:2379,https://127.0.0.1:2379"  
YETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.100.102.72:2380"  
YETCD_ADVERTISE_CLIENT_URLS="https://172.100.102.72:2379"

image-ac48a403
node3:

YETCD_NAME="etcd03"
YETCD_LISTEN_PEER_URLS="https://172.100.102.73:2380"
YETCD_LISTEN_CLIENT_URLS="https://172.100.102.73:2379,https://127.0.0.1:2379"
YETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.100.102.73:2380"
YETCD_ADVERTISE_CLIENT_URLS="https://172.100.102.73:2379"

贴一个运行的命令行, node3的。

/usr/local/etcd/bin/etcd --name etcd03 --initial-advertise-peer-urls https://172.100.102.73:2380 --listen-peer-urls https://172.100.102.73:2380 --listen-client-urls https://172.100.102.73:2379,https://127.0.0.1:2379 --advertise-client-urls https://172.100.102.73:2379 --initial-cluster-token k8s-etcd-cluster --initial-cluster etcd01=https://172.100.102.71:2380,etcd02=https://172.100.102.72:2380,etcd03=https://172.100.102.73:2380 --initial-cluster-state new --client-cert-auth --trusted-ca-file /usr/local/etcd/ssl/cacert.pem --cert-file /usr/local/etcd/ssl/etcd.crt --key-file /usr/local/etcd/ssl/etcd.key --peer-client-cert-auth --peer-trusted-ca-file /usr/local/etcd/ssl/cacert.pem --peer-cert-file /usr/local/etcd/ssl/etcd.crt --peer-key-file /usr/local/etcd/ssl/etcd.key --data-dir /usr/local/etcd/data/data.etcd

三、启动

单台机器启动systemctl可能会卡主,etcd等待其他节点,因为unit文件type是notify会等待etcd返回信号,只要其他节点etcd启动就好了。

 systemctl start etcd

查看日志:

journalctl -u etcd -e
tail -f /var/log/message

查看集群节点信息

[root@k8s-node3 etcd]# bin/etcdctl --cert-file ssl/etcd.crt --key-file ssl/etcd.key --ca-file ssl/cacert.pem --endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" member list
9c6c1c930496e1b5: name=etcd01 peerURLs=https://172.100.102.71:2380 clientURLs=https://172.100.102.71:2379 isLeader=false
eb04b1547bfaa4c0: name=etcd03 peerURLs=https://172.100.102.73:2380 clientURLs=https://172.100.102.73:2379 isLeader=true
fc69ccbe4820e8a9: name=etcd02 peerURLs=https://172.100.102.72:2380 clientURLs=https://172.100.102.72:2379 isLeader=false
[root@k8s-node3 etcd]# 

查看集群健康

[root@k8s-node3 etcd]# bin/etcdctl --cert-file ssl/etcd.crt --key-file ssl/etcd.key --ca-file ssl/cacert.pem --endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" cluster-health
member 9c6c1c930496e1b5 is healthy: got healthy result from https://172.100.102.71:2379
member eb04b1547bfaa4c0 is healthy: got healthy result from https://172.100.102.73:2379
member fc69ccbe4820e8a9 is healthy: got healthy result from https://172.100.102.72:2379
cluster is healthy
[root@k8s-node3 etcd]# 

etcdctl v3 命令不一样了

[root@k8s-node3 etcd]# export ETCDCTL_API=3
[root@k8s-node3 etcd]# bin/etcdctl --cert ssl/etcd.crt --key ssl/etcd.key --cacert ssl/cacert.pem --endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" member list
9c6c1c930496e1b5, started, etcd01, https://172.100.102.71:2380, https://172.100.102.71:2379
eb04b1547bfaa4c0, started, etcd03, https://172.100.102.73:2380, https://172.100.102.73:2379
fc69ccbe4820e8a9, started, etcd02, https://172.100.102.72:2380, https://172.100.102.72:2379
[root@k8s-node3 etcd]# bin/etcdctl --cert ssl/etcd.crt --key ssl/etcd.key --cacert ssl/cacert.pem --endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" endpoint health
https://172.100.102.72:2379 is healthy: successfully committed proposal: took = 10.995576ms
https://172.100.102.73:2379 is healthy: successfully committed proposal: took = 11.061548ms
https://172.100.102.71:2379 is healthy: successfully committed proposal: took = 13.213925ms
[root@k8s-node3 etcd]# bin/etcdctl --cert ssl/etcd.crt --key ssl/etcd.key --cacert ssl/cacert.pem --endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" endpoint status
https://172.100.102.71:2379, 9c6c1c930496e1b5, 3.3.17, 20 kB, false, 8, 13
https://172.100.102.72:2379, fc69ccbe4820e8a9, 3.3.17, 20 kB, false, 8, 13
https://172.100.102.73:2379, eb04b1547bfaa4c0, 3.3.17, 20 kB, true, 8, 13
[root@k8s-node3 etcd]# bin/etcdctl --cert ssl/etcd.crt --key ssl/etcd.key --cacert ssl/cacert.pem --endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" check perf
 60 / 60 Boooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo! 100.00%1m0s
PASS: Throughput is 150 writes/s
PASS: Slowest request took 0.209437s
PASS: Stddev is 0.019801s
PASS

默认端口号:
2380: 和同伴通信。
2379: 供客户端访问。

附加

后边加的, 做个记录, 在etcd使用同一套证书时,简化参数。


Unit:

[Unit]
Description=Etcd server
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
EnvironmentFile=/opt/etcd/conf/etcd.conf
ExecStart=/opt/etcd/etcd \
--name ${name} \
--data-dir ${data_dir} \
--listen-peer-urls https://${local_ip}:2380 \
--initial-advertise-peer-urls https://${local_ip}:2380 \
--listen-client-urls https://${local_ip}:2379,https://127.0.0.1:2379 \
--advertise-client-urls https://${local_ip}:2379 \
--initial-cluster ${initial_cluster} \
--initial-cluster-state "new" \
--initial-cluster-token "mycluster" \
--cert-file ${cert_file} \
--key-file ${key_file} \
--client-crl-file ${client_crl_file} \
--trusted-ca-file ${trusted_ca_file} \
--client-cert-auth \
--peer-cert-file ${cert_file} \
--peer-key-file ${key_file} \
--peer-trusted-ca-file ${trusted_ca_file} \
--peer-client-cert-auth

Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Conf:

name="etcd1"
data_dir="/opt/etcd/data"
local_ip="192.168.1.231"
initial_cluster="etcd1=https://192.168.1.231:2380,etcd2=https://192.168.1.232:2380,etcd3=https://192.168.1.233:2380"
cert_file="/opt/etcd/cert/etcd.crt"
key_file="/opt/etcd/cert/etcd.key"
client_crl_file="/opt/etcd/cert/crl.pem"
trusted_ca_file="/opt/etcd/cert/cacert.pem"