1. etcd 簡介
coreos 開發的分布式服務系統,內部采用 raft 協議作為一致性算法。作為服務發現系統,有以下的特點:
- 簡單:安裝配置簡單,而且提供了 HTTP API 進行交互,使用也很簡單
- 安全:支持 SSL 證書驗證
- 快速:根據官方提供的 benchmark 數據,單實例支持每秒 2k+ 讀操作
- 可靠:采用 raft 算法,實現分布式系統數據的可用性和一致性
在這篇文章編寫的時候,etcd 已經發布了 3.4.13 版本,被被用在 CoreOS、kubernetes、Cloud Foundry 等項目中。
etcd 目前默認使用 2379
端口提供 HTTP API 服務,2380
端口和 peer 通信(這兩個端口已經被 IANA 官方預留給 etcd);在之前的版本中,可能會分別使用 4001
和 7001
,在使用的過程中需要注意這個區別。
雖然 etcd 也支持單點部署,但是在生產環境中推薦集群方式部署,一般 etcd 節點數會選擇 3、5、7。etcd 會保證所有的節點都會保存數據,並保證數據的一致性和正確性。
2. etcd 主要功能
基本的 key-value 存儲
監聽機制
key 的過期及續約機制,用於監控和服務發現
原子 CAS 和 CAD,用於分布式鎖和 leader 選舉
3. etcd 環境准備
操作系統 | ip |
CentOS7.x-86_x64 | 192.268.248.202 |
CentOS7.x-86_x64 | 192.268.248.220 |
CentOS7.x-86_x64 | 192.268.248.224 |
3. etcd 部署
3.1 安裝必要的軟件cfssl(僅192.268.248.202安裝即可)
首先下載安裝包
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
賦予執行權限
chmod +x cfssl*
重命名
for x in cfssl*; do mv $x ${x%*_linux-amd64}; done
移動文件到目錄 (/usr/bin)
mv cfssl* /usr/bin
3.2 配置 CA 並創建 TLS 證書
我們將使用 CloudFlare's PKI 工具 cfssl 來配置 PKI Infrastructure,然后使用它去創建 Certificate Authority(CA), 並為 etcd創建 TLS 證書。
創建目錄
mkdir /opt/etcd/{bin,cfg,ssl} -p cd /opt/etcd/ssl/
etcd ca配置
cat << EOF | tee ca-config.json { "signing": { "default": { "expiry": "87600h" }, "profiles": { "etcd": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } } } EOF
etcd ca證書
cat << EOF | tee ca-csr.json { "CN": "etcd CA", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "Beijing", "ST": "Beijing" } ] } EOF
生成 CA 憑證和私鑰:
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
結果將生成以下兩個文件:
ca-key.pem ca.pem
etcd server證書
cat << EOF | tee server-csr.json { "CN": "etcd", "hosts": [ "192.168.248.202", "192.168.248.220, "192.168.248.224" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "Beijing", "ST": "Beijing" } ] } EOF
生成server證書:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd server-csr.json | cfssljson -bare server
結果將生成以下兩個文件:
server-key.pem server.pem
cfssl安裝參考: https://www.cnblogs.com/stonecode/p/12502399.html
3.3 etcd安裝
下載並解壓縮
ETCD_VER=v3.4.13 # choose either URL GOOGLE_URL=https://storage.googleapis.com/etcd GITHUB_URL=https://github.com/etcd-io/etcd/releases/download DOWNLOAD_URL=${GOOGLE_URL} curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /opt/etcd-${ETCD_VER}-linux-amd64.tar.gz cd /opt && tar -zxvf etcd-v3.4.13-linux-amd64.tar.gz && cd etcd-v3.4.13-linux-amd64 && cp etcd etcdctl /opt/etcd/bin/
配置etcd主文件
vim /opt/etcd/cfg/etcd.conf
#[Member] ETCD_NAME="etcd01" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://192.168.248.202:2380" ETCD_LISTEN_CLIENT_URLS="https://192.168.248.202:2379,http://127.0.0.1:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.248.202:2380" ETCD_ADVERTISE_CLIENT_URLS="https://192.168.248.202:2379" ETCD_INITIAL_CLUSTER="etcd01=https://192.168.248.202:2380,etcd02=https://192.168.248.220:2380,etcd03=https://192.168.248.224:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_ENABLE_V2="true" #[Security] ETCD_CERT_FILE="/opt/etcd/ssl/server.pem" ETCD_KEY_FILE="/opt/etcd/ssl/server-key.pem" ETCD_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem" ETCD_CLIENT_CERT_AUTH="true" ETCD_PEER_CERT_FILE="/opt/etcd/ssl/server.pem" ETCD_PEER_KEY_FILE="/opt/etcd/ssl/server-key.pem" ETCD_PEER_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem" ETCD_PEER_CLIENT_CERT_AUTH="true"
注意:ETCD3.4版本ETCDCTL_API=3 etcdctl 和 etcd --enable-v2=false 成為了默認配置,如要使用v2版本,執行etcdctl時候需要設置ETCDCTL_API環境變量,例如:ETCDCTL_API=2 etcdctl,flannel操作etcd使用的是v2的API,而kubernetes操作etcd使用的v3的API,為了兼容flannel,將默認開啟v2版本,故配置文件中設置 ETCD_ENABLE_V2="true"
配置etcd啟動文件
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 EnvironmentFile=/opt/etcd/cfg/etcd.conf ExecStart=/opt/etcd/bin/etcd Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target
注意:ETCD3.4版本會自動讀取環境變量的參數,所以EnvironmentFile文件中有的參數,不需要再次在ExecStart啟動參數中添加,二選一,如同時配置,會觸發以下類似報錯“etcd: conflicting environment variable "ETCD_NAME" is shadowed by corresponding command-line flag (either unset environment variable or disable flag)”
啟動
systemctl daemon-reload systemctl enable etcd systemctl restart etcd
分發並修改文件到集群另外兩個節點(192.168.248.220、192.168.248.224)
scp -r /opt/etcd/ 192.168.248.220:/opt/ scp -r /opt/etcd/ 192.168.248.224:/opt/ scp /var/lib/systemd/system/etcd.service 192.168.248.220:/var/lib/systemd/system/etcd.service scp /var/lib/systemd/system/etcd.service 192.168.248.224:/var/lib/systemd/system/etcd.service
192.168.248.220 /opt/etcd/cfg/etcd.conf
#[Member] ETCD_NAME="etcd02" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://192.168.248.220:2380" ETCD_LISTEN_CLIENT_URLS="https://192.168.248.220:2379,http://127.0.0.1:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.248.220:2380" ETCD_ADVERTISE_CLIENT_URLS="https://192.168.248.220:2379" ETCD_INITIAL_CLUSTER="etcd01=https://192.168.248.202:2380,etcd02=https://192.168.248.220:2380,etcd03=https://192.168.248.224:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_ENABLE_V2="true" #[Security] ETCD_CERT_FILE="/opt/etcd/ssl/server.pem" ETCD_KEY_FILE="/opt/etcd/ssl/server-key.pem" ETCD_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem" ETCD_CLIENT_CERT_AUTH="true" ETCD_PEER_CERT_FILE="/opt/etcd/ssl/server.pem" ETCD_PEER_KEY_FILE="/opt/etcd/ssl/server-key.pem" ETCD_PEER_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem" ETCD_PEER_CLIENT_CERT_AUTH="true"
192.168.248.224 /opt/etcd/cfg/etcd.conf
#[Member] ETCD_NAME="etcd03" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://192.168.248.224:2380" ETCD_LISTEN_CLIENT_URLS="https://192.168.248.224:2379,http://127.0.0.1:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.248.224:2380" ETCD_ADVERTISE_CLIENT_URLS="https://192.168.248.224:2379" ETCD_INITIAL_CLUSTER="etcd01=https://192.168.248.202:2380,etcd02=https://192.168.248.220:2380,etcd03=https://192.168.248.224:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_ENABLE_V2="true" #[Security] ETCD_CERT_FILE="/opt/etcd/ssl/server.pem" ETCD_KEY_FILE="/opt/etcd/ssl/server-key.pem" ETCD_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem" ETCD_CLIENT_CERT_AUTH="true" ETCD_PEER_CERT_FILE="/opt/etcd/ssl/server.pem" ETCD_PEER_KEY_FILE="/opt/etcd/ssl/server-key.pem" ETCD_PEER_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem" ETCD_PEER_CLIENT_CERT_AUTH="true"
3.4 etcd查看集群狀態
/opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.248.202:2379,https://192.168.248.220:2379,https://192.168.248.224:2379" endpoint status --write-out=table
/opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.248.202:2379,https://192.168.248.220:2379,https://192.168.248.224:2379" endpoint health
/opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.248.202:2379,https://192.168.248.220:2379,https://192.168.248.224:2379" member list
etcd 3.4注意事項:
ETCD3.4版本ETCDCTL_API=3 etcdctl 和 etcd --enable-v2=false 成為了默認配置,如要使用v2版本,執行etcdctl時候需要設置ETCDCTL_API環境變量,例如:ETCDCTL_API=2 etcdctl
ETCD3.4版本會自動讀取環境變量的參數,所以EnvironmentFile文件中有的參數,不需要再次在ExecStart啟動參數中添加,二選一,如同時配置,會觸發以下類似報錯“etcd: conflicting environment variable “ETCD_NAME” is shadowed by corresponding command-line flag (either unset environment variable or disable flag)”
flannel操作etcd使用的是v2的API,而kubernetes操作etcd使用的v3的API
注意:flannel操作etcd使用的是v2的API,而kubernetes操作etcd使用的v3的API,為了兼容flannel,將默認開啟v2版本,故需要配置文件/opt/soft/etcd/etcd.conf中設置 ETCD_ENABLE_V2=“true”