分佈式健值存儲etcd 3.1.7

資源

特性

  • 鍵值對存儲引擎,協議消息使用protobuf
  • 最新版本3.1.5
  • 3.x 版本和 2.x版本 不兼容 3.x是2.x性能的2倍以上,3.x使用gRPC代替了2.x的JSON;etcd3中的租約替代了etc2的TTL;etcd3的事務原子性併發
  • 用於分佈式網絡、服務發現、配置管理、任務調度和負載均衡
  • 單實例可達每秒 1000 次寫操做
  • 一個三成員 etcd 集羣在輕負載下能夠在低於1毫秒內完成一個請求,並在重負載下能夠每秒完成超過 30000 個請求。
  • 支持 SSL 客戶端證書認證加密請求
  • v2和v3 的API使用不一樣的存儲引擎,兩個版本的操做的都是本身的數據 。因此要用v3的api
  • 默認存儲大小爲2GB數據、配置啓動參數 --quota-backend-bytes 能夠最高到8GB。默認每次請求保存的key最大爲1MB。
  • ETCD V3再也不使用目錄結構,只保留鍵。例如:」/a/b/c/「是一個鍵,而不是目錄。V3中提供了前綴查詢,來獲取符合前綴條件的全部鍵值,這變向實現了V2中查詢一個目錄下全部子目錄和節點的功能。
  • 簡潔的響應:像DELETE這類操做成功後將再也不返回操做前的值。若是但願得到刪除前的值,可使用事務,來實現一個原子操做,先獲取鍵值,而後再刪除。
  • 租約:租約代替了V2中的TTL實現,TTL綁定到一個租約上,鍵再附加到這個租約上。當TTL過時時,租約將被銷燬,同時附加到這個租約上的鍵也被刪除。

概念

  • 初始化的問題 若是集羣第一次初始化啓動的時候,有一臺節點未啓動,經過v3的接口訪問的時候,會報告Error: Etcdserver: not capable 錯誤。這是爲兼容性考慮,集羣啓動時默認的API版本是2.3,只有當集羣中的全部節點都加入了,確認全部節點都支持v3接口時,才提高集羣版本到v3。這個只有第一次初始化集羣的時候會遇到,若是集羣已經初始化完畢,再掛掉節點,或者集羣關閉重啓(關閉重啓的時候會從持久化數據中加載集羣API版本),都不會有影響
  • grpc-gateway網關 etcd v3使用gRPC做爲其消息協議。此網關提供RESTful代理,將HTTP / JSON請求轉換爲gRPC消息。

安裝

mkdir -p /opt/etcd-v3.1.7
  curl -sSL http://aliacs-k8s.oss-cn-hangzhou.aliyuncs.com/common/etcd-v3.1.7-linux-amd64.tar.gz| tar xz --strip-components=1 -C /opt/etcd-v3.1.7
  ln -sf /opt/etcd-v3.1.7/etcd /usr/bin/etcd
  ln -sf /opt/etcd-v3.1.7/etcdctl /usr/bin/etcdctl
  etcd --version

mkdir -p /var/lib/etcd;mkdir -p /etc/etcd; groupadd -r etcd; useradd -r -g etcd -d /var/lib/etcd -s /sbin/nologin -c "etcd user" etcd;chown -R etcd:etcd /var/lib/etcd
  
  cat << EOT > /lib/systemd/system/etcd.service
[Unit]
Description=etcd service
After=network.target

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
User=etcd
ExecStart=/usr/bin/etcd --data-dir=data.etcd --name dudu_etcd_245 \
  --initial-advertise-peer-urls http://10.99.73.245:2380 --listen-peer-urls http://10.99.73.245:2380 \ 
  --advertise-client-urls http://10.99.73.245:2379 --listen-client-urls http://10.99.73.245:2379 \
  --initial-cluster dudu_etcd_245=http://10.99.73.245:2380,dudu_etcd_246=http://10.99.73.246:2380 \ 
  --initial-cluster-state new --initial-cluster-token etcd-cluster-dudu-docker
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOT
  
  systemctl daemon-reload
  systemctl enable etcd
  systemctl start etcd
  systemctl status -l etcd.service
  
  檢查集羣健康
  ETCDCTL_API=3 etcdctl endpoint health --endpoints=10.31.75.198:2379,10.29.164.118:2379

經常使用操做命令

  • etcdctl 命令文件是客戶端操做入口 ;使用前設置環境變量 ETCDCTL_API=3 使用3版本的api默認是2版本的
  • export ETCDCTL_API=3

配置

  • 啓動參數:html

    • --listen-client-urls :監聽客戶端通信的URL列表能夠是 0.0.0.0:2379 任何來源 127.0.0.1:2379 本機 以及指定IP
    • --listen-peer-urls : 用於監聽夥伴通信的URL列表 0.0.0.0:2380 任何來源 127.0.0.1:2380 本機 以及指定IP
    • --data-dir: 日誌快照文件保存目錄
    • --name: 成員名 必須惟一
    • --initial-advertise-peer-urls:集羣。列出這個成員的夥伴 URL 以便通告給集羣的其餘成員,集羣可訪問的本機地址
    • --advertise-client-urls:集羣。列出這個成員的客戶端URL,通告給集羣中的其餘成員。
    • --initial-cluster-token: 集羣惟一名
    • --initial-cluster: 集羣成員列表;etcd_node_1=http://10.29.167.233:2380,etcd_node_2=http://10.29.168.24:2380
    • --initial-cluster-state:集羣狀態,值爲 new or existing,new建立靜態或DNS集羣,existing 加入現有集羣
    • --auto-compaction-retention:自動壓縮用於 mvcc 鍵值存儲的保持力(注:應該指多版本保存),單位小時。 0 表示關閉自動壓縮默認爲0關閉 對於服務註冊等只保存運行時動態信息的場合,建議開啓。徹底沒有理由損失存儲空間和效率來保存以前的版本信息。推薦設置爲1,每小時壓縮一次。
  • 集羣啓動
  • 容器集羣啓動node

    #編輯Dockerfile文件
    #Version:1.0                                                        
    FROM alpine:3.5
    MAINTAINER kingcarrot 294865887@qq.com
    #更新日期
    ENV REFRESHED_AT 2017-04-13
    
    #環境變量 啓動容器命令-e參數修改環境變量
    #添加目錄
    #ADD /home/ngrok/data/ /home/data/
    
    WORKDIR /bin
    #USER root
    RUN  apk add --update ca-certificates openssl  tzdata && \
            cp -r -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
            echo "Asia/Shanghai" >  /etc/timezone && \
            apk del --purge  openssl && \
            rm -Rf /var/cache/apk/*
    #添加文件
    COPY  etcd* etcdctl*  /bin/
    
    #掛載目錄
    VOLUME  /data
    #開放端口
    EXPOSE 2379 2380
    
    #啓動命令
    ENTRYPOINT  ["/bin/etcd","--data-dir=/data"]
    
    #構建鏡像
    docker build -t dudu_etcd:v2 .
    #運行容器  第一個運行的節點就是master主機 
    docker run -d -p 2379:2379 -p 2380:2380 --restart=always -v /home/etcd_data:/data --name dudu_etcd_0 dudureg.xip.io:5000/dudu_etcd:v3.0.17 --name etcd_node_0 \
    --initial-advertise-peer-urls http://10.29.167.233:2380 --listen-peer-urls http://0.0.0.0:2380  \
    --advertise-client-urls http://10.29.167.233:2379 --listen-client-urls http://0.0.0.0:2379 \
    --initial-cluster-state new --initial-cluster-token kubernetes_etcd_token_test --auto-compaction-retention=0 \
    --initial-cluster etcd_node_0=http://10.29.167.233:2380,etcd_node_1=http://10.29.167.233:2381,etcd_node_2=http://10.29.167.233:2382
    
    docker run -d -p 2378:2379 -p 2381:2380 --restart=always -v /home/etcd_data_1:/data --name dudu_etcd_1 dudureg.xip.io:5000/dudu_etcd:v3.0.17 --name etcd_node_1 \
    --initial-advertise-peer-urls http://10.29.167.233:2381 --listen-peer-urls http://0.0.0.0:2380  \
    --advertise-client-urls http://10.29.167.233:2378 --listen-client-urls http://0.0.0.0:2379 \
    --initial-cluster-state new --initial-cluster-token kubernetes_etcd_token_test --auto-compaction-retention=0  \
    --initial-cluster etcd_node_0=http://10.29.167.233:2380,etcd_node_1=http://10.29.167.233:2381,etcd_node_2=http://10.29.167.233:2382
    
    docker run -d -p 2377:2379 -p 2382:2380 --restart=always -v /home/etcd_data_2:/data --name dudu_etcd_2 dudureg.xip.io:5000/dudu_etcd:v3.0.17 --name etcd_node_2 \
    --initial-advertise-peer-urls http://10.29.167.233:2382 --listen-peer-urls http://0.0.0.0:2380  \
    --advertise-client-urls http://10.29.167.233:2377 --listen-client-urls http://0.0.0.0:2379 \
    --initial-cluster-state new --initial-cluster-token kubernetes_etcd_token_test --auto-compaction-retention=0 \
    --initial-cluster etcd_node_0=http://10.29.167.233:2380,etcd_node_1=http://10.29.167.233:2381,etcd_node_2=http://10.29.167.233:2382
    
    #容器中 --listen-peer-urls http://0.0.0.0:2380 --listen-client-urls http://0.0.0.0:2379 配置 才能被容器外訪問,但至關於徹底開放出去了,訪問宿主服務器ip 一樣能訪問到etcd;
    #配置爲127.0.0.1 容器外部卻沒法訪問;配置爲宿主IP則沒法啓動etcd;能夠配置阿里雲的服務器安全組拒絕外網對2379和2380的端口訪問
    # --initial-cluster 集羣多成員時,必須所有啓動才能訪問,不然只配置本機爲成員就能夠單機訪問
    
    
    #查看日誌 
    docker logs -f -t --tail=100 dudu_etcd_1
    docker exec -ti dudu_etcd_1 ash 
    export ETCDCTL_API=3 | /bin/etcdctl version
  • 安裝圖形化監控報警工具 Prometheus
  • https://prometheus.io/docs/in... 官網linux

    PROMETHEUS_VERSION="1.3.1"
    wget https://github.com/prometheus/prometheus/releases/download/v$PROMETHEUS_VERSION/prometheus-$PROMETHEUS_VERSION.linux-amd64.tar.gz -O /tmp/prometheus-$PROMETHEUS_VERSION.linux-amd64.tar.gz
    tar -xvzf /tmp/prometheus-$PROMETHEUS_VERSION.linux-amd64.tar.gz --directory /tmp/ --strip-components=1
    /tmp/prometheus -version
    
    #配置監控的集羣
    cat > /tmp/test-etcd.yaml <<EOF
      global:
        scrape_interval: 10s
      scrape_configs:
        - job_name: test-etcd
          static_configs:

EOF
cat /tmp/test-etcd.yamlgit

#啓動成後臺進程 每10秒收集一次數據
nohup /tmp/prometheus \github

-config.file /tmp/test-etcd.yaml \
-web.listen-address ":9090" \
-storage.local.path "test-etcd.data" >> /tmp/test-etcd.log  2>&1 &

#Grafana 內置了Prometheus的支持
只須要添加一個數據源
Name: test-etcd
Type: Prometheus
Url: http://localhost:9090
Access: proxyweb

## 功能

### REST API 請求 都是v2版本的api
* curl http://localhost:2379/version
* curl http://localhost:2379/metrics  監控
* curl http://localhost:2379/health   節點健康存活
* curl http://localhost:2379/v2/stats/leader  查看領導主機狀態
* curl http://localhost:2379/v2/stats/self   查看當前節點自身狀態
* curl http://localhost:2379/v2/stats/store   存儲狀態
* curl http://localhost:2379/v2/members  成員列表
* curl http://localhost:2379/v2/members -XPOST -H "Content-Type: application/json" -d '{"peerURLs":["http://10.0.0.10:2380"]}' 添加成員
* curl http://localhost:2379/v2/members/272e204152 -XDELETE 刪除成員
* curl http://localhost:2379/v2/members/272e204152 -XPUT -H "Content-Type: application/json" -d '{"peerURLs":["http://10.0.0.10:2380"]}' 更改
* curl http://localhost:2379/v2/keys/message -XPUT -d value="Hello world" 添加健值message=Hello world
* curl http://localhost:2379/v2/keys/message  獲取健值
* curl http://localhost:2379/v2/keys/message -XPUT -d value="Hello etcd" 更改健值
* curl http://localhost:2379/v2/keys/message -XDELETE 刪除健值
* curl http://localhost:2379/v2/keys/foo -XPUT -d value=bar -d ttl=5  設置健值生存期
* curl http://localhost:2379/v2/keys/foo?wait=true  持久監視健值變化
* curl http://localhost:2379/v2/keys/dir -XPUT -d dir=true  建立一個目錄 v3版本沒有目錄概念
* curl http://localhost:2379/v2/keys/  列出目錄
* curl http://localhost:2379/v2/keys/foo_dir?dir=true -XDELETE 清空目錄
* curl http://localhost:2379/v2/keys/dir?recursive=true -XDELETE 刪除目錄

### v3版本的API
* 注意:key和value 的值必須是base64編碼以後的字符串 無需傳參的數據仍是必須是空json的body體 和必須是POST請求類型
* https://coreos.com/etcd/docs/3.1.5/dev-guide/apispec/swagger/rpc.swagger.json  全部的接口定義
* https://coreos.com/etcd/docs/3.1.5/dev-guide/api_reference_v3.html#service-cluster-etcdserveretcdserverpbrpcproto 接口文檔
* https://github.com/coreos/etcd/blob/8fdfac2843f68144d4cc0d74713a036316b1fd45/etcdserver/etcdserverpb/rpc.proto  源代碼查看接口
* curl -L http://localhost:2379/v3alpha/kv/put     -X POST -d '{"key": "Zm9v", "value": "YmFy"}'  設置值
* curl -L http://localhost:2379/v3alpha/kv/range -X POST -d '{"key": "Zm9v"}'  查看指定範圍的健值
* curl -L http://localhost:2379/v3alpha/watch  -X POST -d '{"create_request": {"key":"Zm9v"} }' &  監視健值的變化
* curl -L http://localhost:2379/v3alpha/cluster/member/list -X POST -d '{}'  查當作員列表
* curl -L http://localhost:2379/v3alpha/kv/deleterange -X POST -d '{"key": "Zm9v"}' 刪除指定範圍的數據

### etcdctl 命令請求
* docker exec -ti dudu_etcd_0 ash 
* export ETCDCTL_API=3 使用命令以前肯定使用的API版本默認是2
* etcdctl version  版本
* etcdctl 命令 --endpoints=10.30.187.25:2379 加上請求地址參數
* etcdctl member list --endpoints=10.30.187.25:2379 集羣成員;列出成員ID,集羣的peerURLs參數和集羣的clientURLs參數
* etcdctl cluster-health 集羣健康
* etcdctl member update a8266ecf031671f3 http://10.0.1.10:2380  更新節點peerURLs
* etcdctl member remove a8266ecf031671f3 刪除節點 
* etcdctl member add etcd_node_3 http://10.0.1.13:2380  新增節點
* etcdctl put keys "{aa:1, bb: 2}" --endpoints=10.30.187.25:2379  保存鍵值
* etcdctl get keys  獲取鍵值
* etcdctl get --endpoints=10.30.187.25:2379 --prefix=true ""  獲取全部值
* etcdctl get --prefix=true "/kubernetes" 獲取指定前綴的全部健值
* etcdctl del keys  刪除健值
* etcdctl del --endpoints=10.30.187.25:2379 --prefix=true "/kubernetes"  刪除指定前綴的全部健值返回刪除數量
* etcdctl watch keys  監視健值
* etcdctl compaction 壓縮歷史數據  etcd支持歷史數據的讀取,爲了不積累無限歷史數據。compacting操做後,etcd將刪除歷史的版本數據,釋放資源爲後面使用。在compacted 版本前的數據都將無效。
* etcdctl defrag    對指定成員碎片整理
* etcdctl snapshot save  backup.db 保存快照
* etcdctl snapshot status backup.db 快照狀態
* etcdctl snapshot restore  backup.db 從指定文件恢復快照
* etcdctl --endpoints=127.0.0.1:2379 endpoint status  查看狀態

## 維護
* https://coreos.com/etcd/docs/3.1.5/upgrades/upgrade_3_1.html  3.0升級到3.1 零停機,滾動升級
* 升級集羣主機,建議一次升級一個成員,中止master是能夠的,但會有短暫的選舉停頓
* 要替換健康的單個成員,請添加一個新成員,而後刪除舊成員
* 維持在三個成員配置集羣
* etcdctl --write-out=table endpoint status  節點狀態查看
* etcdctl alarm list    查看警告列表

## 調試

## 優化
* 容器時區配置問題:

ls -l /etc/localtime 主機上查看本地時區docker

yaml文件中將本地時區文件加載到pod容器中/etc/localtime
volumeMounts:json

- name: tz-config
    mountPath: /etc/localtime
volumes:
  - name: tz-config
    hostPath:
       path: /usr/share/zoneinfo/Asia/Shanghai

單容器配置指定時區
docker run -it --rm -e "TZ=Asia/Shanghai" centos:7 date +%Zcentos

## 常見問題
相關文章
相關標籤/搜索