以下是个人搭建etcd集群中的记录,首先使用这篇文章中介绍的脚本创建三个虚拟机,ubuntu-01、
ubuntu-02、ubuntu-03,在三台虚拟机中分别安装 etcd
sudo apt install etcd
安装完成之后打开 /lib/systemd/system/etcd.service 这个service文件
[Unit]
Description=etcd - highly-available key value store
Documentation=https://etcd.io/docs
Documentation=man:etcd
After=network.target
Wants=network-online.target
[Service]
Environment=DAEMON_ARGS=
Environment=ETCD_NAME=%H
Environment=ETCD_DATA_DIR=/var/lib/etcd/default
EnvironmentFile=-/etc/default/%p
Type=notify
User=etcd
PermissionsStartOnly=true
#ExecStart=/bin/sh -c "GOMAXPROCS=$(nproc) /usr/bin/etcd $DAEMON_ARGS"
ExecStart=/usr/bin/etcd $DAEMON_ARGS
Restart=on-abnormal
#RestartSec=10s
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Alias=etcd2.service
这个是etcd的service文件,可以看到etcd的配置文件在/etc/defalut/目录中,名称应该是etcd,这个和传统的不一致,我们需要在/etc/etcd/目录中存放配置文件,有两种选择,修改这里的EnvironmentFile,或者把/etc/etcd目录中文件链接到 /etc/default 中,我这里选择第二种方式。
注意如果选择第一种方式,修改完成之后要运行 systemctl daemon-reload etcd让新的配置生效。
修改之后,下面我们来配置etcd集群,我们需要配置一个安全的高可用集群。
下面的内容,应该在**宿主机(HOST)**机器中先生成,然后我们用脚本一键配置,避免出错
-
创建ca 根证书
#创建一个工作目录 mkdir etcd cd etcd openssl genrsa -out ca.key 2048 openssl req -x509 -new -nodes -key ca.key -subj "/CN=etcd-peer" -days 36500 -out ca.crt
-
创建etcd的服务端ca证书
创建之前首先要有证书的SAN配置文件,如果使用的是kvm下面的虚拟机,可以使用下面的脚本生成
#!/bin/bash # 文件保存为generate-ssl-config.sh vm_list=$(sudo virsh list --state-running | awk 'NR > 2 { print $2 }') cat >etcd_ssl.cnf <<EOF [ req ] req_extensions = v3_req distinguished_name = req_distinguished_name [ req_distinguished_name ] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [ alt_names ] EOF IFS=',' read -ra items <<<"$1" count=1 for item in "${items[@]}"; do ip=$(sudo virsh domifaddr "$item" | awk '/ipv4/ {print $4}' | cut -d'/' -f1) echo "IP.$count = $ip" >>etcd_ssl.cnf ((count++)) done
生成的类似于如下格式的文件(etcd_ssl.cnf):
[ req ] req_extensions = v3_req distinguished_name = req_distinguished_name [ req_distinguished_name ] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [ alt_names ] IP.1 = 192.168.122.182 IP.2 = 192.168.122.134 IP.3 = 192.168.122.168
开始创建证书
openssl genrsa -out etcd_server.key 2048 openssl req -new -key etcd_server.key -config etcd_ssl.cnf -subj "/CN=etcd-server" -out etcd_server.csr openssl x509 -req -in etcd_server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile etcd_ssl.cnf -out etcd_server.crt
-
创建etcd客户端证书
openssl genrsa -out etcd_client.key 2048 openssl req -new -key etcd_client.key -config etcd_ssl.cnf -subj "/CN=etcd-client" -out etcd_client.csr openssl x509 -req -in etcd_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile etcd_ssl.cnf -out etcd_client.crt
-
创建etcd配置文件
这里我们依然使用脚本生成
#!/bin/bash # 文件保存为generate-etcd-conf.sh generate() { local name="$1" local ip=$(sudo virsh domifaddr "$name" | awk '/ipv4/ {print $4}' | cut -d'/' -f1) cat >"$name.etcd.conf" <<EOF # 节点的名称,每个节点都应该不同 ETCD_NAME=$name # etcd数据存放目录 ETCD_DATA_DIR=/etc/etcd/data # 服务端证书和key ETCD_CERT_FILE=/etc/etcd/pki/etcd_server.crt ETCD_KEY_FILE=/etc/etcd/pki/etcd_server.key # 信任ca根证书 ETCD_TRUSTED_CA_FILE=/etc/kubernetes/pki/ca.crt ETCD_CLIENT_CERT_AUTH=true # 客户端连接的地址 ETCD_LISTEN_CLIENT_URLS=https://$ip:2379 ETCD_ADVERTISE_CLIENT_URLS=https://$ip:2379 # 集群节点间相互认证的证书和key ETCD_PEER_CERT_FILE=/etc/etcd/pki/etcd_server.crt ETCD_PEER_KEY_FILE=/etc/etcd/pki/etcd_server.key # 信任ca根证书 ETCD_PEER_TRUSTED_CA_FILE=/etc/kubernetes/pki/ca.crt # 其他节点连接的地址 ETCD_LISTEN_PEER_URLS=https://$ip:2380 ETCD_INITIAL_ADVERTISE_PEER_URLS=https://$ip:2380 # 集群的名称 ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster # 初始化集群的状态,新建集群设置为"new",加入集群的时候设置为"existing", ETCD_INITIAL_CLUSTER_STATE=new EOF } # 拆分参数字符串为数组 IFS=',' read -ra items <<<"$1" etcdCluesters="" # 遍历数组并调用函数 for item in "${items[@]}"; do generate $item ip=$(sudo virsh domifaddr "$item" | awk '/ipv4/ {print $4}' | cut -d'/' -f1) if [ -z "$etcdCluesters" ]; then etcdCluesters="$item=https://$ip:2380" else etcdCluesters="$etcdCluesters,$item=https://$ip:2380" fi done for item in "${items[@]}"; do echo "ETCD_INITIAL_CLUSTER=\"$etcdCluesters\"" >>"$item.etcd.conf" done
保存为文件之后,直接执行
./generate-etcd-conf.sh ubuntu-01,ubuntu-02,ubuntu-03
会在当前的目录生成三个配置文件生成的配置文件类似于下面的格式:
ETCD_NAME=ubuntu-01 ETCD_DATA_DIR=/etc/etcd/data ETCD_CERT_FILE=/etc/etcd/pki/etcd_server.crt ETCD_KEY_FILE=/etc/etcd/pki/etcd_server.key ETCD_TRUSTED_CA_FILE=/etc/kubernetes/pki/ca.crt ETCD_CLIENT_CERT_AUTH=true ETCD_LISTEN_CLIENT_URLS=https://192.168.122.140:2379 ETCD_ADVERTISE_CLIENT_URLS=https://192.168.122.140:2379 ETCD_PEER_CERT_FILE=/etc/etcd/pki/etcd_server.crt ETCD_PEER_KEY_FILE=/etc/etcd/pki/etcd_server.key ETCD_PEER_TRUSTED_CA_FILE=/etc/kubernetes/pki/ca.crt ETCD_LISTEN_PEER_URLS=https://192.168.122.140:2380 ETCD_INITIAL_ADVERTISE_PEER_URLS=https://192.168.122.140:2380 ETCD_INITIAL_CLUSTER_TOKEN=etca-cluster ETCD_INITIAL_CLUSTER_STATE=new ETCD_INITIAL_CLUSTER="ubuntu-01=https://192.168.122.140:2380,ubuntu-02=https://192.168.122.100:2380,ubuntu-03=https://192.168.122.165:2380"
-
最后我们再创建一个脚本,帮助我们,一键配置etcd
#!/bin/bash # 文件保存为 config-etcd.sh # 先放在这里,我们后面会安装kubernetes sudo mkdir -p /etc/kubernetes/pki sudo mkdir -p /etc/etcd/pki sudo mkdir -p /etc/etcd/data sudo cp ./ca.* /etc/kubernetes/pki sudo cp ./etcd_server.* /etc/etcd/pki sudo cp ./etcd_client.* /etc/etcd/pki sudo chown -R etcd /etc/etcd/data sudo chown -R etcd /etc/etcd/pki sudo mv /etc/default/etcd /etc/default/etcd.bak sudo ln -s /etc/etcd/etcd.conf /etc/default/etcd
-
最后一步把我们的生成的文件分别传到我们的机器上
ca.crt ca.key ca.srl config-etcd.sh etcd_client.crt etcd_client.csr etcd_client.key etcd_server.crt etcd_server.csr etcd_server.key etcd_ssl.cnf generate-etcd-conf.sh generate-ssl-config.sh ubuntu-01.etcd.conf ubuntu-02.etcd.conf ubuntu-03.etcd.conf
#先打包一下 tar -cvzf etcd.tar.gz etcd/ # 使用scp传输到服务器上 scp etcd.tar.gz ubuntu-01:/home/ubuntu # 解压运行 config-etcd.sh
-
验证集群运行情况
#使用v3的api export ETCDCTL_API=3 #查看集群运行情况 etcdctl --cacert=/etc/kubernetes/pki/ca.crt --cert=/etc/etcd/pki/etcd_client.crt --key=/etc/etcd/pki/etcd_client.key --endpoints=https://192.168.122.140:2379,https://192.168.122.100:2379,https://192.168.122.189:2379 endpoint health
注意这里的cacert、cert 我们都可以放在环境变量中,放在.bashrc文件中,这样在使用etcdctl的时候,就不用每一次都写长长的参数了,类似于下面这种
export ETCDCTL_API=3 export ETCDCTL_ENDPOINTS=“https://192.168.122.140:2379,https://192.168.122.100:2379,https://192.168.122.189:2379” export ETCDCTL_CACERT="/etc/kubernetes/pki/ca.crt" export ETCDCTL_CERT="/etc/etcd/pki/etcd_client.crt" export ETCDCTL_KEY="/etc/etcd/pki/etcd_client.key"
如果输出是类似于下面的内容,表示集群搭建成功
https://192.168.122.140:2379 is healthy: successfully committed proposal: took = 14.744654ms https://192.168.122.100:2379 is healthy: successfully committed proposal: took = 15.038352ms https://192.168.122.189:2379 is healthy: successfully committed proposal: took = 17.155474ms
-
向已有集群中添加新的节点
假设我们新创建了一个新的机器 ubuntu-04(这里使用新的机器的方式)
首先,需要创建新的证书,这里需要修改证书配置文件,把新的机器的ip地址放进去192.168.122.170
[ req ] req_extensions = v3_req distinguished_name = req_distinguished_name [ req_distinguished_name ] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [ alt_names ] IP.1 = 192.168.122.182 IP.2 = 192.168.122.134 IP.3 = 192.168.122.168 IP.4 = 192.168.122.170
然后用之前的根证书(注意一定要用上一次的根证书),生成新的证书,生成证书的命令和上面一致,和上面节点一样,配置好证书。
在任意节点的机器上运行
export ETCDCTL_API=3 export ETCDCTL_ENDPOINTS="https://192.168.122.140:2379,https://192.168.122.100:2379,https://192.168.122.165:2379,https://192.168.122.189:2379" export ETCDCTL_CACERT="/etc/kubernetes/pki/ca.crt" export ETCDCTL_CERT="/etc/etcd/pki/etcd_client.crt" export ETCDCTL_KEY="/etc/etcd/pki/etcd_client.key" etcdctl member add ubuntu-04 --peer-urls=https://192.168.122.165:2380
成功之后,会输出如下的内容:
Member 75bf29390cd64d5e added to cluster ab21a525ae2568ae ETCD_NAME="ubuntu-04" ETCD_INITIAL_CLUSTER="ubuntu-02=https://192.168.122.100:2380,ubuntu-04=https://192.168.122.165:2380,ubuntu-03=https://192.168.122.165:2380,ubuntu-01=https://192.168.122.140:2380" ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.122.165:2380" ETCD_INITIAL_CLUSTER_STATE="existing"
然后把这一段内容,放到etcd的配置文件中,然后启动etcd,再次 运行
etcdctl endpoint health
,如果出现类似于下面的内容,则表示,新节点加入成功https://192.168.122.140:2379 is healthy: successfully committed proposal: took = 14.744654ms https://192.168.122.100:2379 is healthy: successfully committed proposal: took = 15.038352ms https://192.168.122.189:2379 is healthy: successfully committed proposal: took = 17.155474ms https://192.168.122.165:2379 is healthy: successfully committed proposal: took = 17.762056ms
完整的配置脚本见:https://github.com/lihuu/dotfiles/tree/master/etcd