0 專輯概述
etcd 是雲原生架構中重要的基礎組件,由 CNCF 孵化托管。etcd 在微服務和 Kubernates 集群中不僅可以作為服務注冊與發現,還可以作為 key-value 存儲的中間件。
《徹底搞懂 etcd 系列文章》將會從 etcd 的基本功能實踐、API 接口、實現原理、源碼分析,以及實現中的踩坑經驗等幾方面具體展開介紹 etcd。預計會有 20 篇左右的文章,筆者將會每周持續更新,歡迎關注。
1 etcd 安裝與使用
在上一篇主要介紹了 etcd 的相關概念和使用場景,本篇主要介紹 etcd 的多種安裝使用方式。
1.1 etcd 概念詞匯表
在開始 etcd 的安裝使用之前,我們先了解下 etcd 的概念詞匯表,以便於下文的理解。
- Raft:etcd所采用的保證分布式系統強一致性的算法。
- Node:一個Raft狀態機實例。
- Member: 一個etcd實例。它管理着一個Node,並且可以為客戶端請求提供服務。
- Cluster:由多個Member構成可以協同工作的etcd集群。
- Peer:對同一個etcd集群中另外一個Member的稱呼。
- Client: 向etcd集群發送HTTP請求的客戶端。
- WAL:預寫式日志,etcd用於持久化存儲的日志格式。
- snapshot:etcd防止WAL文件過多而設置的快照,存儲etcd數據狀態。
- Proxy:etcd的一種模式,為etcd集群提供反向代理服務。
- Leader:Raft算法中通過競選而產生的處理所有數據提交的節點。
- Follower:競選失敗的節點作為Raft中的從屬節點,為算法提供強一致性保證。
- Candidate:當Follower超過一定時間接收不到Leader的心跳時轉變為Candidate開始競選。
- Term:某個節點成為Leader到下一次競選時間,稱為一個Term。
- Index:數據項編號。Raft中通過Term和Index來定位數據。
2 etcd 單機安裝部署
etcd 的安裝有多種方式,筆者以 Centos 7 和 MacOS 10.15 為例,可以通過 yum install etcd
和 brew install etcd
進行安裝。
然而通過系統工具安裝的 etcd 版本比較滯后,如果需要安裝最新版本的 etcd ,我們可以通過二進制包、源碼編譯以及 docker 容器安裝。
2.1 二進制安裝
目前最新的 etcd 版本為 3.4.4。在 macOS 下,執行如下的腳本:
ETCD_VER=v3.4.4
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GITHUB_URL}
rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-darwin-amd64.zip -o /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
unzip /tmp/etcd-${ETCD_VER}-darwin-amd64.zip -d /tmp && rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
mv /tmp/etcd-${ETCD_VER}-darwin-amd64/* /tmp/etcd-download-test && rm -rf mv /tmp/etcd-${ETCD_VER}-darwin-amd64
/tmp/etcd-download-test/etcd --version
/tmp/etcd-download-test/etcdctl version
即可輸出如下的結果:
etcd Version: 3.4.4
Git SHA: c65a9e2dd
Go Version: go1.12.12
Go OS/Arch: darwin/amd64
可以看到,我們已經成功包裝了 etcd 3.4.4,且該版本基於的 Go 版本為 1.12.12
。
同樣,我們在 Centos 7 上面使用如下的腳本進行安裝:
ETCD_VER=v3.4.4
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GITHUB_URL}
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
/tmp/etcd-download-test/etcd --version
/tmp/etcd-download-test/etcdctl version
下載可能比較慢,執行完之后,結果如下:
etcd Version: 3.4.4
Git SHA: e784ba73c
Go Version: go1.12.12
Go OS/Arch: linux/amd64
這樣我們在 macOS 和 Linux 都已安裝成功,關於 Windows 系統的安裝比較簡單,下載好安裝包后,直接執行。其中 etcd.exe 是服務端,etcdctl.exe 是客戶端。
2.2 源碼安裝
使用源碼安裝,首先需要確保本地的 Go 語言環境。如未安裝,請參考 https://golang.org/doc/install。
對於那些想嘗試最新版本的人,可以從 master 分支構建 etcd。需要 Go 版本為 1.13+,來構建最新版本的 etcd。 本地的 Go 版本為:
$ go version
$ go version go1.13.6 linux/amd64
基於 master 分支構建 etcd,腳本如下:
git clone https://github.com/etcd-io/etcd.git
cd etcd
./build
執行測試命令,確保 etcd 編譯安裝成功:
$ ./etcdctl version
etcdctl version: 3.4.4
API version: 3.4
經過如上的步驟,已經通過源碼編譯安裝成功 etcd。
2.3 docker 容器安裝
etcd 使用 gcr.io/etcd-development/etcd
作為容器倉庫源,而 quay.io/coreos/etcd
作為輔助容器注冊表。
REGISTRY=quay.io/coreos/etcd
# available from v3.2.5
REGISTRY=gcr.io/etcd-development/etcd
rm -rf /tmp/etcd-data.tmp && mkdir -p /tmp/etcd-data.tmp && \
docker rmi gcr.io/etcd-development/etcd:v3.4.7 || true && \
docker run \
-p 2379:2379 \
-p 2380:2380 \
--mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data \
--name etcd-gcr-v3.4.7 \
gcr.io/etcd-development/etcd:v3.4.7 \
/usr/local/bin/etcd \
--name s1 \
--data-dir /etcd-data \
--listen-client-urls http://0.0.0.0:2379 \
--advertise-client-urls http://0.0.0.0:2379 \
--listen-peer-urls http://0.0.0.0:2380 \
--initial-advertise-peer-urls http://0.0.0.0:2380 \
--initial-cluster s1=http://0.0.0.0:2380 \
--initial-cluster-token tkn \
--initial-cluster-state new \
--log-level info \
--logger zap \
--log-outputs stderr
docker exec etcd-gcr-v3.4.7 /bin/sh -c "/usr/local/bin/etcd --version"
docker exec etcd-gcr-v3.4.7 /bin/sh -c "/usr/local/bin/etcdctl version"
docker exec etcd-gcr-v3.4.7 /bin/sh -c "/usr/local/bin/etcdctl endpoint health"
docker exec etcd-gcr-v3.4.7 /bin/sh -c "/usr/local/bin/etcdctl put foo bar"
docker exec etcd-gcr-v3.4.7 /bin/sh -c "/usr/local/bin/etcdctl get foo"
執行如下命令,確認容器安裝的 etcd 的狀態:
$ etcdctl --endpoints=http://localhost:2379 version
etcdctl version: 3.4.4
API version: 3.4
3. etcd 集群部署
在生產環境中,為了整個集群的高可用,etcd 正常都會集群部署,避免單點故障。本節將會介紹如何進行 etcd 集群部署。
3.1 本地運行一個 etcd 集群
如果想要在一台機器上實踐 etcd 集群的搭建,可以通過 goreman 工具。
goreman 是一個 Go 語言編寫的多進程管理工具,是對 Ruby 下廣泛使用的 foreman 的重寫(foreman 原作者也實現了一個 Go 版本:forego,不過沒有 goreman 好用)。
我們前面已經確認過 Go 安裝環境,直接執行:
go get github.com/mattn/goreman
編譯后的文件放在 $GOPATH/bin
中,$GOPATH/bin
目錄已經添加到了系統 $PATH
中,所以我們可以方便執行命令 goreman
命令。下面就是編寫 Procfile 腳本,我們啟動三個 etcd,具體對應如下:
HostName | ip | 客戶端交互端口 | peer 通信端口
:-: | :-: | :-: | :-:
infra1 | 127.0.0.1 | 12379 | 12380 |
infra2 | 127.0.0.1| 22379 | 22380 |
infra3 | 127.0.0.1| 32379 | 32380 |
Procfile 腳本如下:
etcd1: etcd --name infra1 --listen-client-urls http://127.0.0.1:12379 --advertise-client-urls http://127.0.0.1:12379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger=zap --log-outputs=stderr
etcd2: etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger=zap --log-outputs=stderr
etcd3: etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger=zap --log-outputs=stderr
配置項說明:
- --name:etcd集群中的節點名,這里可以隨意,可區分且不重復就行
- --listen-peer-urls:監聽的用於節點之間通信的url,可監聽多個,集群內部將通過這些url進行數據交互(如選舉,數據同步等)
- --initial-advertise-peer-urls:建議用於節點之間通信的url,節點間將以該值進行通信。
- --listen-client-urls:監聽的用於客戶端通信的url,同樣可以監聽多個。
- --advertise-client-urls:建議使用的客戶端通信 url,該值用於 etcd 代理或 etcd 成員與 etcd 節點通信。
- --initial-cluster-token: etcd-cluster-1,節點的 token 值,設置該值后集群將生成唯一 id,並為每個節點也生成唯一 id,當使用相同配置文件再啟動一個集群時,只要該 token 值不一樣,etcd 集群就不會相互影響。
- --initial-cluster:也就是集群中所有的 initial-advertise-peer-urls 的合集。
- --initial-cluster-state:new,新建集群的標志
注意上面的腳本,etcd 命令執行時需要根據本地實際的安裝地址進行配置。下面我們啟動 etcd 集群。
goreman -f /opt/procfile start
使用如上的命令啟動啟動 etcd 集群,啟動完成之后查看集群內的成員。
$ etcdctl --endpoints=http://localhost:22379 member list
8211f1d0f64f3269, started, infra1, http://127.0.0.1:12380, http://127.0.0.1:12379, false
91bc3c398fb3c146, started, infra2, http://127.0.0.1:22380, http://127.0.0.1:22379, false
fd422379fda50e48, started, infra3, http://127.0.0.1:32380, http://127.0.0.1:32379, false
我們在單機搭建的偽集群成功,需要注意的是在集群啟動時,我們是通過靜態的方式指定集群的成員,在實際環境中,集群成員的 ip 可能不會提前知道。這時候就需要采用動態發現的機制。
4. 小結
本章較為簡單,偏向實踐,讀者最好能夠自己動手實踐一遍。本文主要介紹了 etcd 的多種安裝方式: etcd 單機和 etcd 集群的方式。etcd 集群的安裝,還需要配合服務發現的動態機制,將會在下一篇具體講解,歡迎關注點贊。