<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用 StatefulSet 部署 etcd 集群

          共 21000字,需瀏覽 42分鐘

           ·

          2020-11-19 19:04

          上文我們簡單介紹了 etcd 的基本概念和使用場景,本文就來介紹如何搭建 etcd 集群。在生產(chǎn)環(huán)境中,為了整個集群的高可用,etcd 正常都會以集群方式部署,避免單點故障。引導(dǎo) etcd 集群的啟動有以下三種機制:

          • 靜態(tài)
          • etcd 動態(tài)發(fā)現(xiàn)
          • DNS 發(fā)現(xiàn)

          靜態(tài)啟動 etcd 集群要求每個成員都知道集群中的另一個成員。在許多情況下,群集成員的 IP 可能未知,在這些情況下,可以在發(fā)現(xiàn)服務(wù)的幫助下引導(dǎo) etcd 集群。

          可以使用官方提供的工具來生成 etcd 集群的配置:http://play.etcd.io/install

          這里我們將主要介紹靜態(tài)方式啟動 etcd 集群。

          安裝

          由于 etcd 是基于 raft 分布式協(xié)議的集群,所以如果要組成一個集群,集群的數(shù)量需要奇數(shù)臺。如果只有一個節(jié)點的話我們也可以通過不同的端口來進行模擬,比如這里我們在一臺機器上來安裝一個3節(jié)點的 etcd 偽集群,對應(yīng)的配置如下所示:


          這里我們在一臺 CentOS7 系統(tǒng)的節(jié)點上來進行演示,首先下載 etcd 二進制包,直接從 github release 頁面下載對應(yīng)的包即可:

          $?wget?https://github.com/etcd-io/etcd/releases/download/v3.4.13/etcd-v3.4.13-linux-amd64.tar.gz
          $?tar?-xvf?etcd-v3.4.13-linux-amd64.tar.gz
          $?mkdir?/tmp/etcd?
          $?mv?etcd-v3.4.13-linux-amd64/etcd?/tmp/etcd/
          $?mv?etcd-v3.4.13-linux-amd64/etcdctl?/tmp/etcd

          etcd 安裝完成后,啟動3個不同的終端分別執(zhí)行下面的3個命令來啟動 etcd 集群:

          #?確保?etcd?進程對數(shù)據(jù)目錄具有寫訪問權(quán)
          #?如果集群是新集群,則刪除該目錄;如果重新啟動則保留該目錄

          #?啟動第一個節(jié)點
          $?/tmp/etcd/etcd?--name?s1?\??#?etcd?節(jié)點名稱
          ??--data-dir?/tmp/etcd/s1?\??#?數(shù)據(jù)存儲目錄?
          ??--listen-client-urls?http://localhost:2379?\??#?本節(jié)點訪問地址
          ??--advertise-client-urls?http://localhost:2379?\??#?用于通知其他?ETCD?節(jié)點,客戶端接入本節(jié)點的監(jiān)聽地址
          ??--listen-peer-urls?http://localhost:2380?\??#?本節(jié)點與其他節(jié)點進行數(shù)據(jù)交換的監(jiān)聽地址
          ??--initial-advertise-peer-urls?http://localhost:2380?\??#?通知其他節(jié)點與本節(jié)點進行數(shù)據(jù)交換的地址
          ??--initial-cluster?s1=http://localhost:2380,s2=http://localhost:22380,s3=http://localhost:32380?\??#?集群所有節(jié)點配置
          ??--initial-cluster-token?tkn?\??#?集群唯一標(biāo)識
          ??--initial-cluster-state?new??#?節(jié)點初始化方式

          #?啟動第二個節(jié)點
          $?/tmp/etcd/etcd?--name?s2?\
          ??--data-dir?/tmp/etcd/s2?\
          ??--listen-client-urls?http://localhost:22379?\
          ??--advertise-client-urls?http://localhost:22379?\
          ??--listen-peer-urls?http://localhost:22380?\
          ??--initial-advertise-peer-urls?http://localhost:22380?\
          ??--initial-cluster?s1=http://localhost:2380,s2=http://localhost:22380,s3=http://localhost:32380?\
          ??--initial-cluster-token?tkn?\
          ??--initial-cluster-state?new

          #?啟動第三個節(jié)點
          $?/tmp/etcd/etcd?--name?s3?\
          ??--data-dir?/tmp/etcd/s3?\
          ??--listen-client-urls?http://localhost:32379?\
          ??--advertise-client-urls?http://localhost:32379?\
          ??--listen-peer-urls?http://localhost:32380?\
          ??--initial-advertise-peer-urls?http://localhost:32380?\
          ??--initial-cluster?s1=http://localhost:2380,s2=http://localhost:22380,s3=http://localhost:32380?\
          ??--initial-cluster-token?tkn?\
          ??--initial-cluster-state?new

          正常啟動完成后,我們可以使用 etcdctl 命令來查看集群的狀態(tài):

          $?ETCDCTL_API=3?/tmp/etcd/etcdctl?\
          ??--endpoints?localhost:2379,localhost:22379,localhost:32379?\
          ??endpoint?health
          localhost:2379?is?healthy:?successfully?committed?proposal:?took?=?14.22105ms
          localhost:22379?is?healthy:?successfully?committed?proposal:?took?=?13.058173ms
          localhost:32379?is?healthy:?successfully?committed?proposal:?took?=?16.497453ms
          $?ETCDCTL_API=3?/tmp/etcd/etcdctl?\
          ??--endpoints?localhost:2379,localhost:22379,localhost:32379?\?
          ??endpoint?status?--write-out=table
          +-----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
          |????ENDPOINT?????|????????ID????????|?VERSION?|?DB?SIZE?|?IS?LEADER?|?IS?LEARNER?|?RAFT?TERM?|?RAFT?INDEX?|?RAFT?APPLIED?INDEX?|?ERRORS?|
          +-----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
          |??localhost:2379?|?7339c4e5e833c029?|??3.4.13?|???20?kB?|??????true?|??????false?|????????43?|??????????9?|??????????????????9?|????????|
          |?localhost:22379?|?729934363faa4a24?|??3.4.13?|???20?kB?|?????false?|??????false?|????????43?|??????????9?|??????????????????9?|????????|
          |?localhost:32379?|??b548c2511513015?|??3.4.13?|???20?kB?|?????false?|??????false?|????????43?|??????????9?|??????????????????9?|????????|
          +-----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

          正常可以看到3個 etcd 節(jié)點都運行成功了,也可以查看當(dāng)前集群的 LEADER 節(jié)點。如果這個時候我們把 2379 端口的進程殺掉,再來查看集群的狀態(tài):

          $?ETCDCTL_API=3?/tmp/etcd/etcdctl???--endpoints?localhost:2379,localhost:22379,localhost:32379??endpoint?status?--write-out=table
          {"level":"warn","ts":"2020-11-16T14:39:25.024+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying?of?unary?invoker?failed","target":"passthrough:///localhost:2379","attempt":0,"error":"rpc?error:?code?=?DeadlineExceeded?desc?=?latest?balancer?error:?connection?error:?desc?=?\"transport:?Error?while?dialing?dial?tcp?[::1]:2379:?connect:?connection?refused\""}
          Failed?to?get?the?status?of?endpoint?localhost:2379?(context?deadline?exceeded)
          +-----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
          |????ENDPOINT?????|????????ID????????|?VERSION?|?DB?SIZE?|?IS?LEADER?|?IS?LEARNER?|?RAFT?TERM?|?RAFT?INDEX?|?RAFT?APPLIED?INDEX?|?ERRORS?|
          +-----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
          |?localhost:22379?|?729934363faa4a24?|??3.4.13?|???20?kB?|??????true?|??????false?|????????44?|?????????10?|?????????????????10?|????????|
          |?localhost:32379?|??b548c2511513015?|??3.4.13?|???20?kB?|?????false?|??????false?|????????44?|?????????10?|?????????????????10?|????????|
          +-----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

          可以看到現(xiàn)在集群中只有兩個節(jié)點,但是現(xiàn)在集群還是可以正常使用的,因為我們一共3個節(jié)點,現(xiàn)在還有超過一一半的節(jié)點正常,那么集群就是正常的,當(dāng)然如果我們再關(guān)閉一個節(jié)點那么我們集群就將處于不健康的狀態(tài)下了。

          參數(shù)說明

          上面我們成功搭建了 etcd 的集群,etcd 在啟動過程中有很多參數(shù)可以配置,這里我們就先來對這些參數(shù)進行一個簡單的說明。

          • --name :節(jié)點名稱

            默認(rèn)值:default

            環(huán)境變量:ETCD_NAME

            說明:這個值和 --initial-cluster 參數(shù)中的 key 值一一對應(yīng),如果在集群環(huán)境中,name 必須是唯一的,建議用主機名稱或者機器 ID。

          • --data-dir:數(shù)據(jù)存儲目錄

            默認(rèn)值:${name}.etcd

            環(huán)境變量:ETCD_DATA_DIR

          • --wal-dir:存放預(yù)寫日志目錄

            默認(rèn)值:""

            環(huán)境變量:ETCD_WAL_DIR

            說明:最大的作用是記錄了整個數(shù)據(jù)變化的全部歷程,如果未配置則共用 --data-dir 文件所在目錄。

          • --snapshot-count:數(shù)據(jù)快照觸發(fā)數(shù)量

            默認(rèn)值:100000

            環(huán)境變量:ETCD_SNAPSHOT_COUNT

            說明:etcd 處理指定次數(shù)的事務(wù)提交后,生產(chǎn)數(shù)據(jù)快照

          • --heartbeat-interval:客戶端連接后的心跳間隔(毫秒)

            默認(rèn)值:100

            環(huán)境變量:ETCD_HEARTBEAT_INTERVAL

          • --election-timeout**:**集群選舉的超時時間

            默認(rèn)值:1000

            環(huán)境變量:ETCD_ELECTION_TIMEOUT

          • --max-snapshots:最大快照數(shù)量,0表示不限制

            默認(rèn)值:5

            環(huán)境變量:ETCD_MAX_SNAPSHOTS

          • --max-wals:最大預(yù)寫日志數(shù)量,0表示不限制

            默認(rèn)值:5

            環(huán)境變量:ETCD_MAX_WAL

          • --listen-peer-urls:本節(jié)點使用,用于監(jiān)聽其他節(jié)點發(fā)送信息的地址,地址寫法是 scheme://IP:port

            默認(rèn)值:http://localhost:2380

            環(huán)境變量:ETCD_LISTEN_PEER_URL

            示例:http://10.0.0.1:2380

            無效的示例:http://example.com:2380 (域名對綁定無效)

          • --listen-client-urls:本節(jié)點使用,用于 etcd 客戶端通信的 url,寫法是 scheme://IP:port,可以多個并用逗號隔開

            默認(rèn)值:http://localhost:2379

            示例:http://10.0.0.1:2379

            無效的示例:http://example.com:2379 (域名對綁定無效)

          • --initial-advertise-peer-urls:其他節(jié)點通過該地址與本節(jié)點進行數(shù)據(jù)交換(選舉,同步)的地址,URL 可以使用域名地址

            默認(rèn)值:http://localhost:2380

            環(huán)境變量:ETCD_INITIAL_ADVERTISE_PEER_URL

            說明:與 --listener-peer-urls 不同在于 listener-peer-urls 用于請求客戶端的接入控制,initial-advertise-peer-urls 是告知其他集群節(jié)點訪問哪個 URL,一般來說,initial-advertise-peer-urlsl 將是 listene-peer-urls 的子集。靜態(tài)配置方式下,該參數(shù)值一定要同時在 --initial-cluster 參數(shù)中存在

          • --advertise-client-urls :用于通知其他 ETCD 節(jié)點,客戶端接入本節(jié)點的監(jiān)聽地址,一般來說 advertise-client-urls 是 listen-client-urls 子集

            默認(rèn)值:http://localhost:2379

            環(huán)境變量:ETCD_ADVERTISE_CLIENT_URL

          • --initial-cluster :集群所有節(jié)點配置,多個用逗號隔開

            默認(rèn)值:http://localhost:2380

            環(huán)境變量:ETCD_INITIAL_CLUSTER

            說明:key 是所提供的每個節(jié)點的 --name 標(biāo)志的值

          • --initial-cluster-state :節(jié)點初始化方式

            默認(rèn)值:new

            環(huán)境變量:ETCD_INITIAL_CLUSTER_STATE

            說明:new 表示如果沒有集群不存在,創(chuàng)建新集群,existing 表示如果集群不存在,節(jié)點將處于加入集群失敗狀態(tài)。

          • --initial-cluster-token :集群唯一標(biāo)識

            默認(rèn)值:etcd-cluster

            環(huán)境變量:ETCD_INITIAL_CLUSTER_TOKEN

            說明:相同標(biāo)識的節(jié)點將視為在一個集群內(nèi)

          在 Kubernetes 集群中部署

          我們現(xiàn)在了解了 etcd 集群的基本搭建方式,那么我們應(yīng)該如何將其運行到 Kubernetes 集群中呢?畢竟我們是要來編寫 Operator 的,所以我們肯定需要先知道怎么能夠在 Kubernetes 集群中運行起來。

          這里我們可以使用 StatefulSet 這個控制器來運行 etcd 集群,etcd 集群的編排的資源清單文件我們可以使用 Kubernetes 源碼中提供的,位于目錄:test/e2e/testing-manifests/statefulset/etcd 下面。

          $?ls?-la?test/e2e/testing-manifests/statefulset/etcd??
          total?40
          drwxr-xr-x???6?ych??staff???192?Jun?18??2019?.
          drwxr-xr-x??10?ych??staff???320?Oct?10??2018?..
          -rw-r--r--???1?ych??staff???173?Oct?10??2018?pdb.yaml
          -rw-r--r--???1?ych??staff???242?Oct?10??2018?service.yaml
          -rw-r--r--???1?ych??staff??6441?Jun?18??2019?statefulset.yaml
          -rw-r--r--???1?ych??staff???550?Oct?10??2018?tester.yaml

          其中 service.yaml 文件中就是一個用戶 StatefulSet 使用的 headless service:

          apiVersion:?v1
          kind:?Service
          metadata:
          ??name:?etcd
          ??labels:
          ????app:?etcd
          spec:
          ??ports:
          ??-?port:?2380
          ????name:?etcd-server
          ??-?port:?2379
          ????name:?etcd-client
          ??clusterIP:?None
          ??selector:
          ????app:?etcd
          ??publishNotReadyAddresses:?true

          pdb.yaml 文件是用來保證 etcd 的高可用的一個 PodDisruptionBudget 資源對象:

          apiVersion:?policy/v1beta1
          kind:?PodDisruptionBudget
          metadata:
          ??name:?etcd-pdb
          ??labels:
          ????pdb:?etcd
          spec:
          ??minAvailable:?2
          ??selector:
          ????matchLabels:
          ??????app:?etcd

          最重要的當(dāng)然是 statefulset.yaml 文件,但是這個文件有很多 bug,比如在上面參數(shù)配置的時候我們就提到過 --listen-peer-urls 和 ?--listen-client-urls 這兩個參數(shù)的值是不支持域名的綁定形式的,而這里使用的 http://${HOSTNAME}.${SET_NAME} 這個 FQDN 形式的域名,所以啟動失敗了,我們需要將其修改為 IP 的形式,要獲取 Pod 的 IP 地址也很簡單,我們可以通過 Kubernetes 提供的 Downward API 來注入一個 POD_IP 的環(huán)境變量來獲取,然后將這兩個參數(shù)值改成 http://${POD_IP}:PORT 即可。另外這個資源清單文件的鏡像版本太老了,而且沒有支持 V3 版本的 API,所以這里我們升級下鏡像,讓其支持 V3 版本的接口。修改過后的完整資源清單文件如下所示:

          apiVersion:?apps/v1
          kind:?StatefulSet
          metadata:
          ??labels:
          ????app:?etcd
          ??name:?etcd
          spec:
          ??replicas:?3
          ??selector:
          ????matchLabels:
          ??????app:?etcd
          ??serviceName:?etcd
          ??template:
          ????metadata:
          ??????labels:
          ????????app:?etcd
          ????spec:
          ??????containers:
          ????????-?name:?etcd
          ??????????image:?cnych/etcd:v3.4.13
          ??????????imagePullPolicy:?IfNotPresent
          ??????????ports:
          ??????????-?containerPort:?2380
          ????????????name:?peer
          ????????????protocol:?TCP
          ??????????-?containerPort:?2379
          ????????????name:?client
          ????????????protocol:?TCP
          ??????????env:
          ??????????-?name:?INITIAL_CLUSTER_SIZE
          ????????????value:?"3"
          ??????????-?name:?MY_NAMESPACE
          ????????????valueFrom:
          ??????????????fieldRef:
          ????????????????fieldPath:?metadata.namespace
          ??????????-?name:?POD_IP
          ????????????valueFrom:
          ??????????????fieldRef:
          ????????????????fieldPath:?status.podIP
          ??????????-?name:?SET_NAME
          ????????????value:?"etcd"
          ??????????command:
          ????????????-?/bin/sh
          ????????????-?-ec
          ????????????-?|
          ??????????????HOSTNAME=$(hostname)

          ??????????????ETCDCTL_API=3

          ??????????????eps()?{
          ??????????????????EPS=""
          ??????????????????for?i?in?$(seq?0?$((${INITIAL_CLUSTER_SIZE}?-?1)));?do
          ??????????????????????EPS="${EPS}${EPS:+,}http://${SET_NAME}-${i}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local:2379"
          ??????????????????done
          ??????????????????echo?${EPS}
          ??????????????}

          ??????????????member_hash()?{
          ??????????????????etcdctl?member?list?|?grep?-w?"$HOSTNAME"?|?awk?'{?print?$1}'?|?awk?-F?","?'{?print?$1}'
          ??????????????}

          ??????????????initial_peers()?{
          ??????????????????PEERS=""
          ??????????????????for?i?in?$(seq?0?$((${INITIAL_CLUSTER_SIZE}?-?1)));?do
          ????????????????????PEERS="${PEERS}${PEERS:+,}${SET_NAME}-${i}=http://${SET_NAME}-${i}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local:2380"
          ??????????????????done
          ??????????????????echo?${PEERS}
          ??????????????}

          ??????????????#?etcd-SET_ID
          ??????????????SET_ID=${HOSTNAME##*-}

          ??????????????#?adding?a?new?member?to?existing?cluster?(assuming?all?initial?pods?are?available)
          ??????????????if?[?"${SET_ID}"?-ge?${INITIAL_CLUSTER_SIZE}?];?then
          ??????????????????#?export?ETCDCTL_ENDPOINTS=$(eps)
          ??????????????????#?member?already?added?

          ??????????????????MEMBER_HASH=$(member_hash)
          ??????????????????if?[?-n?"${MEMBER_HASH}"?];?then
          ??????????????????????#?the?member?hash?exists?but?for?some?reason?etcd?failed
          ??????????????????????#?as?the?datadir?has?not?be?created,?we?can?remove?the?member
          ??????????????????????#?and?retrieve?new?hash
          ??????????????????????echo?"Remove?member?${MEMBER_HASH}"
          ??????????????????????etcdctl?--endpoints=$(eps)?member?remove?${MEMBER_HASH}
          ??????????????????fi

          ??????????????????echo?"Adding?new?member"

          ??????????????????echo?"etcdctl?--endpoints=$(eps)?member?add?${HOSTNAME}?--peer-urls=http://${HOSTNAME}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local:2380"
          ??????????????????etcdctl?member?--endpoints=$(eps)?add?${HOSTNAME}?--peer-urls=http://${HOSTNAME}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local:2380?|?grep?"^ETCD_"?>?/var/run/etcd/new_member_envs

          ??????????????????if?[?$??-ne?0?];?then
          ??????????????????????echo?"member?add?${HOSTNAME}?error."
          ??????????????????????rm?-f?/var/run/etcd/new_member_envs
          ??????????????????????exit?1
          ??????????????????fi

          ??????????????????echo?"==>?Loading?env?vars?of?existing?cluster..."
          ??????????????????sed?-ie?"s/^/export?/"?/var/run/etcd/new_member_envs
          ??????????????????cat?/var/run/etcd/new_member_envs
          ??????????????????.?/var/run/etcd/new_member_envs

          ??????????????????echo?"etcd?--name?${HOSTNAME}?--initial-advertise-peer-urls?${ETCD_INITIAL_ADVERTISE_PEER_URLS}?--listen-peer-urls?http://${POD_IP}:2380?--listen-client-urls?http://${POD_IP}:2379,http://127.0.0.1:2379?--advertise-client-urls?http://${HOSTNAME}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local:2379?--data-dir?/var/run/etcd/default.etcd?--initial-cluster?${ETCD_INITIAL_CLUSTER}?--initial-cluster-state?${ETCD_INITIAL_CLUSTER_STATE}"

          ??????????????????exec?etcd?--listen-peer-urls?http://${POD_IP}:2380?\
          ??????????????????????--listen-client-urls?http://${POD_IP}:2379,http://127.0.0.1:2379?\
          ??????????????????????--advertise-client-urls?http://${HOSTNAME}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local:2379?\
          ??????????????????????--data-dir?/var/run/etcd/default.etcd
          ??????????????fi

          ??????????????for?i?in?$(seq?0?$((${INITIAL_CLUSTER_SIZE}?-?1)));?do
          ??????????????????while?true;?do
          ??????????????????????echo?"Waiting?for?${SET_NAME}-${i}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local?to?come?up"
          ??????????????????????ping?-W?1?-c?1?${SET_NAME}-${i}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local?>?/dev/null?&&?break
          ??????????????????????sleep?1s
          ??????????????????done
          ??????????????done

          ??????????????echo?"join?member?${HOSTNAME}"
          ??????????????#?join?member
          ??????????????exec?etcd?--name?${HOSTNAME}?\
          ??????????????????--initial-advertise-peer-urls?http://${HOSTNAME}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local:2380?\
          ??????????????????--listen-peer-urls?http://${POD_IP}:2380?\
          ??????????????????--listen-client-urls?http://${POD_IP}:2379,http://127.0.0.1:2379?\
          ??????????????????--advertise-client-urls?http://${HOSTNAME}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local:2379?\
          ??????????????????--initial-cluster-token?etcd-cluster-1?\
          ??????????????????--data-dir?/var/run/etcd/default.etcd?\
          ??????????????????--initial-cluster?$(initial_peers)?\
          ??????????????????--initial-cluster-state?new
          ??????????lifecycle:
          ????????????preStop:
          ??????????????exec:
          ????????????????command:
          ??????????????????-?/bin/sh
          ??????????????????-?-ec
          ??????????????????-?|
          ????????????????????HOSTNAME=$(hostname)

          ????????????????????member_hash()?{
          ????????????????????????etcdctl?member?list?|?grep?-w?"$HOSTNAME"?|?awk?'{?print?$1}'?|?awk?-F?","?'{?print?$1}'
          ????????????????????}

          ????????????????????eps()?{
          ????????????????????????EPS=""
          ????????????????????????for?i?in?$(seq?0?$((${INITIAL_CLUSTER_SIZE}?-?1)));?do
          ????????????????????????????EPS="${EPS}${EPS:+,}http://${SET_NAME}-${i}.${SET_NAME}.${MY_NAMESPACE}.svc.cluster.local:2379"
          ????????????????????????done
          ????????????????????????echo?${EPS}
          ????????????????????}

          ????????????????????export?ETCDCTL_ENDPOINTS=$(eps)
          ????????????????????SET_ID=${HOSTNAME##*-}

          ????????????????????#?Removing?member?from?cluster
          ????????????????????if?[?"${SET_ID}"?-ge?${INITIAL_CLUSTER_SIZE}?];?then
          ????????????????????????echo?"Removing?${HOSTNAME}?from?etcd?cluster"
          ????????????????????????etcdctl?member?remove?$(member_hash)
          ????????????????????????if?[?$??-eq?0?];?then
          ????????????????????????????#?Remove?everything?otherwise?the?cluster?will?no?longer?scale-up
          ????????????????????????????rm?-rf?/var/run/etcd/*
          ????????????????????????fi
          ????????????????????fi
          ??????????volumeMounts:
          ??????????-?mountPath:?/var/run/etcd
          ????????????name:?datadir
          ??volumeClaimTemplates:
          ??-?metadata:
          ??????name:?datadir
          ????spec:
          ??????accessModes:
          ??????-?"ReadWriteOnce"
          ??????resources:
          ????????requests:
          ??????????#?upstream?recommended?max?is?700M
          ??????????storage:?1Gi

          修改完成后,我們在 Kubernetes 集群中創(chuàng)建上面的幾個資源對象:

          ???etcd?git:(1e11e4a2108)???kubectl?apply?-f?pdb.yaml?????????????????????????????
          poddisruptionbudget.policy/etcd-pdb?created
          ???etcd?git:(1e11e4a2108)???kubectl?apply?-f?service.yaml?
          service/etcd?created
          ???etcd?git:(1e11e4a2108)???kubectl?apply?-f?statefulset.yaml?
          statefulset.apps/etcd?created
          ???etcd?git:(1e11e4a2108)???kubectl?get?pods?-l?app=etcd?????
          NAME?????READY???STATUS????RESTARTS???AGE
          etcd-0???1/1?????Running???0??????????5m35s
          etcd-1???1/1?????Running???0??????????5m12s
          etcd-2???1/1?????Running???0??????????4m51s

          需要注意上面的 StatefulSet 需要3個可用的 1G 容量 ReadWriteOnce 模式的 PV

          現(xiàn)在我們可以看到 etcd 集群就啟動成功了,同樣我們可以查看集群現(xiàn)在的狀態(tài):

          ???etcd?git:(1e11e4a2108)???kubectl?exec?-it?etcd-0?/bin/sh??????????????????????????????????????????????????????????????????????????
          #?etcdctl?--endpoints?etcd-0.etcd:2379,etcd-1.etcd:2379,etcd-2.etcd:2379?endpoint?status?--write-out=table
          +------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
          |?????ENDPOINT?????|????????ID????????|?VERSION?|?DB?SIZE?|?IS?LEADER?|?IS?LEARNER?|?RAFT?TERM?|?RAFT?INDEX?|?RAFT?APPLIED?INDEX?|?ERRORS?|
          +------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
          |?etcd-0.etcd:2379?|?2e80f96756a54ca9?|??3.4.13?|???20?kB?|??????true?|??????false?|?????????2?|??????????9?|??????????????????9?|????????|
          |?etcd-1.etcd:2379?|?7fd61f3f79d97779?|??3.4.13?|???20?kB?|?????false?|??????false?|?????????2?|??????????9?|??????????????????9?|????????|
          |?etcd-2.etcd:2379?|?b429c86e3cd4e077?|??3.4.13?|???20?kB?|?????false?|??????false?|?????????2?|??????????9?|??????????????????9?|????????|
          +------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

          我們可以嘗試去刪除其中一個 Pod 來驗證集群是否正常,Pod 重建后是否還可以加入到集群中去。比如我們執(zhí)行下面的命令將集群擴容到5個副本:

          ???etcd?git:(1e11e4a2108)???kubectl?scale?--replicas=5?statefulset?etcd
          ???etcd?git:(1e11e4a2108)???kubectl?get?pods?-l?app=etcd???????????????
          NAME?????READY???STATUS????RESTARTS???AGE
          etcd-0???1/1?????Running???0??????????5m59s
          etcd-1???1/1?????Running???0??????????5m52s
          etcd-2???1/1?????Running???0??????????5m47s
          etcd-3???1/1?????Running???0??????????4m
          etcd-4???1/1?????Running???1??????????3m55s

          此時我們再去查看集群的狀態(tài):

          ???etcd?git:(1e11e4a2108)???kubectl?exec?-it?etcd-0?/bin/sh????????????
          #?etcdctl?--endpoints?etcd-0.etcd:2379,etcd-1.etcd:2379,etcd-2.etcd:2379,etcd-3.etcd:2379,etcd-4.etcd:2379?endpoint?status?--write-out=table
          +------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
          |?????ENDPOINT?????|????????ID????????|?VERSION?|?DB?SIZE?|?IS?LEADER?|?IS?LEARNER?|?RAFT?TERM?|?RAFT?INDEX?|?RAFT?APPLIED?INDEX?|?ERRORS?|
          +------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
          |?etcd-0.etcd:2379?|?c799a6ef06bc8c14?|??3.4.13?|???20?kB?|?????false?|??????false?|????????16?|?????????13?|?????????????????13?|????????|
          |?etcd-1.etcd:2379?|?9869f0647883a00d?|??3.4.13?|???20?kB?|??????true?|??????false?|????????16?|?????????13?|?????????????????13?|????????|
          |?etcd-2.etcd:2379?|?42c8b94265b9b79a?|??3.4.13?|???20?kB?|?????false?|??????false?|????????16?|?????????13?|?????????????????13?|????????|
          |?etcd-3.etcd:2379?|?41eec5480dc0d9ec?|??3.4.13?|???20?kB?|?????false?|??????false?|????????16?|?????????13?|?????????????????13?|????????|
          |?etcd-4.etcd:2379?|?ebbc833cba01ecad?|??3.4.13?|???20?kB?|?????false?|??????false?|????????16?|?????????13?|?????????????????13?|????????|
          +------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

          當(dāng)然同樣也可以去對其進行縮容操作:

          ???etcd?git:(1e11e4a2108)???kubectl?scale?--replicas=3?statefulset?etcd
          statefulset.apps/etcd?scaled
          ???etcd?git:(1e11e4a2108)???kubectl?get?pods?-l?app=etcd???????????????
          NAME?????READY???STATUS????RESTARTS???AGE
          etcd-0???1/1?????Running???0??????????11m
          etcd-1???1/1?????Running???0??????????28s
          etcd-2???1/1?????Running???0??????????23s
          ???etcd?git:(1e11e4a2108)???kubectl?exec?-it?etcd-0?/bin/sh????????????
          #?etcdctl?--endpoints?etcd-0.etcd:2379,etcd-1.etcd:2379,etcd-2.etcd:2379?endpoint?status?--write-out=table
          +------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
          |?????ENDPOINT?????|????????ID????????|?VERSION?|?DB?SIZE?|?IS?LEADER?|?IS?LEARNER?|?RAFT?TERM?|?RAFT?INDEX?|?RAFT?APPLIED?INDEX?|?ERRORS?|
          +------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
          |?etcd-0.etcd:2379?|?2e80f96756a54ca9?|??3.4.13?|???20?kB?|??????true?|??????false?|???????139?|?????????23?|?????????????????23?|????????|
          |?etcd-1.etcd:2379?|?7fd61f3f79d97779?|??3.4.13?|???20?kB?|?????false?|??????false?|???????139?|?????????23?|?????????????????23?|????????|
          |?etcd-2.etcd:2379?|?b429c86e3cd4e077?|??3.4.13?|???20?kB?|?????false?|??????false?|???????139?|?????????23?|?????????????????23?|????????|
          +------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

          現(xiàn)在又變回我們的集群模式了。


          訓(xùn)練營推薦





          ?點擊屏末?|??|?即刻學(xué)習(xí)

          瀏覽 64
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  噜噜噜噜影院 | 日本一二三区视频在线 | 黄色一级在线电影 | 午夜水蜜桃 | 国产大鸡八 |