On each etcd node, specify the cluster members:

Run this on each machine:

  1. THIS_NAME=${NAME_1}
  2. THIS_IP=${HOST_1}
  3. etcd --data-dir=data.etcd --name ${THIS_NAME} \
  4. --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
  5. --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
  6. --initial-cluster ${CLUSTER} \
  7. --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
  8. # For machine 2
  9. THIS_NAME=${NAME_2}
  10. THIS_IP=${HOST_2}
  11. etcd --data-dir=data.etcd --name ${THIS_NAME} \
  12. --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
  13. --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
  14. --initial-cluster ${CLUSTER} \
  15. --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
  16. # For machine 3
  17. THIS_NAME=${NAME_3}
  18. THIS_IP=${HOST_3}
  19. etcd --data-dir=data.etcd --name ${THIS_NAME} \
  20. --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
  21. --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
  22. --initial-cluster ${CLUSTER} \
  23. --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}

Or use our public discovery service:

  1. curl https://discovery.etcd.io/new?size=3
  2. https://discovery.etcd.io/a81b5818e67a6ea83e9d4daea5ecbc92
  3. # grab this token
  4. TOKEN=token-01
  5. CLUSTER_STATE=new
  6. NAME_1=machine-1
  7. NAME_2=machine-2
  8. NAME_3=machine-3
  9. HOST_1=10.240.0.17
  10. HOST_2=10.240.0.18
  11. HOST_3=10.240.0.19
  12. DISCOVERY=https://discovery.etcd.io/a81b5818e67a6ea83e9d4daea5ecbc92
  13. THIS_NAME=${NAME_1}
  14. THIS_IP=${HOST_1}
  15. etcd --data-dir=data.etcd --name ${THIS_NAME} \
  16. --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
  17. --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
  18. --discovery ${DISCOVERY} \
  19. --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
  20. THIS_NAME=${NAME_2}
  21. THIS_IP=${HOST_2}
  22. etcd --data-dir=data.etcd --name ${THIS_NAME} \
  23. --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
  24. --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
  25. --discovery ${DISCOVERY} \
  26. --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
  27. THIS_NAME=${NAME_3}
  28. THIS_IP=${HOST_3}
  29. etcd --data-dir=data.etcd --name ${THIS_NAME} \
  30. --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
  31. --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
  32. --discovery ${DISCOVERY} \
  33. --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}

Now etcd is ready! To connect to etcd with etcdctl:

  1. export ETCDCTL_API=3
  2. HOST_1=10.240.0.17
  3. HOST_2=10.240.0.18
  4. HOST_3=10.240.0.19
  5. ENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379
  6. etcdctl --endpoints=$ENDPOINTS member list

Access etcd

02_etcdctl_access_etcd_2016051001

put command to write:

  1. etcdctl --endpoints=$ENDPOINTS put foo "Hello World!"

get to read from etcd:

  1. etcdctl --endpoints=$ENDPOINTS --write-out="json" get foo

Get by prefix

  1. etcdctl --endpoints=$ENDPOINTS put web1 value1
  2. etcdctl --endpoints=$ENDPOINTS put web2 value2
  3. etcdctl --endpoints=$ENDPOINTS put web3 value3
  4. etcdctl --endpoints=$ENDPOINTS get web --prefix

Delete

04_etcdctl_delete_2016050601

  1. etcdctl --endpoints=$ENDPOINTS put user1 bad
  2. etcdctl --endpoints=$ENDPOINTS txn --interactive
  3. compares:
  4. value("user1") = "bad"
  5. success requests (get, put, delete):
  6. del user1
  7. failure requests (get, put, delete):
  8. put user1 good

Watch

watch to get notified of future changes:

06_etcdctl_watch_2016050501

  1. etcdctl --endpoints=$ENDPOINTS watch stock1
  2. etcdctl --endpoints=$ENDPOINTS put stock1 1000
  3. etcdctl --endpoints=$ENDPOINTS watch stock --prefix
  4. etcdctl --endpoints=$ENDPOINTS put stock1 10
  5. etcdctl --endpoints=$ENDPOINTS put stock2 20

Lease

lease to write with TTL:

  1. etcdctl --endpoints=$ENDPOINTS lease grant 300
  2. # lease 2be7547fbc6a5afa granted with TTL(300s)
  3. etcdctl --endpoints=$ENDPOINTS put sample value --lease=2be7547fbc6a5afa
  4. etcdctl --endpoints=$ENDPOINTS get sample
  5. etcdctl --endpoints=$ENDPOINTS lease keep-alive 2be7547fbc6a5afa
  6. etcdctl --endpoints=$ENDPOINTS lease revoke 2be7547fbc6a5afa
  7. # or after 300 seconds
  8. etcdctl --endpoints=$ENDPOINTS get sample

Distributed locks

lock for distributed lock:

08_etcdctl_lock_2016050501

  1. etcdctl --endpoints=$ENDPOINTS lock mutex1
  2. # another client with the same name blocks
  3. etcdctl --endpoints=$ENDPOINTS lock mutex1

elect for leader election:

  1. etcdctl --endpoints=$ENDPOINTS elect one p1
  2. # another client with the same name blocks
  3. etcdctl --endpoints=$ENDPOINTS elect one p2

Cluster status

Specify the initial cluster configuration for each machine:

  1. etcdctl --write-out=table --endpoints=$ENDPOINTS endpoint status
  2. +------------------+------------------+---------+---------+-----------+-----------+------------+
  3. | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
  4. +------------------+------------------+---------+---------+-----------+-----------+------------+
  5. | 10.240.0.17:2379 | 4917a7ab173fabe7 | 3.0.0 | 45 kB | true | 4 | 16726 |
  6. | 10.240.0.18:2379 | 59796ba9cd1bcd72 | 3.0.0 | 45 kB | false | 4 | 16726 |
  7. | 10.240.0.19:2379 | 94df724b66343e6c | 3.0.0 | 45 kB | false | 4 | 16726 |
  8. +------------------+------------------+---------+---------+-----------+-----------+------------+

Snapshot

snapshot to save point-in-time snapshot of etcd database:

11_etcdctl_snapshot_2016051001

  1. etcdctl --endpoints=$ENDPOINTS snapshot save my.db
  2. Snapshot saved at my.db
  1. etcdctl --write-out=table --endpoints=$ENDPOINTS snapshot status my.db
  2. +---------+----------+------------+------------+
  3. | HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
  4. +---------+----------+------------+------------+
  5. | c55e8b8 | 9 | 13 | 25 kB |
  6. +---------+----------+------------+------------+

Migrate

migrate to transform etcd v2 to v3 data:

  1. # write key in etcd version 2 store
  2. export ETCDCTL_API=2
  3. etcdctl --endpoints=http://$ENDPOINT set foo bar
  4. # read key in etcd v2
  5. etcdctl --endpoints=$ENDPOINTS --output="json" get foo
  6. # stop etcd node to migrate, one by one
  7. # migrate v2 data
  8. export ETCDCTL_API=3
  9. etcdctl --endpoints=$ENDPOINT migrate --data-dir="default.etcd" --wal-dir="default.etcd/member/wal"
  10. # restart etcd node after migrate, one by one
  11. # confirm that the key got migrated
  12. etcdctl --endpoints=$ENDPOINTS get /foo

member to add,remove,update membership:

13_etcdctl_member_2016062301

  1. # For each machine
  2. TOKEN=my-etcd-token-1
  3. CLUSTER_STATE=new
  4. NAME_1=etcd-node-1
  5. NAME_2=etcd-node-2
  6. NAME_3=etcd-node-3
  7. HOST_1=10.240.0.13
  8. HOST_3=10.240.0.15
  9. CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380
  10. # For node 1
  11. THIS_NAME=${NAME_1}
  12. etcd --data-dir=data.etcd --name ${THIS_NAME} \
  13. --initial-advertise-peer-urls http://${THIS_IP}:2380 \
  14. --listen-peer-urls http://${THIS_IP}:2380 \
  15. --advertise-client-urls http://${THIS_IP}:2379 \
  16. --listen-client-urls http://${THIS_IP}:2379 \
  17. --initial-cluster ${CLUSTER} \
  18. --initial-cluster-state ${CLUSTER_STATE} \
  19. --initial-cluster-token ${TOKEN}
  20. # For node 2
  21. THIS_NAME=${NAME_2}
  22. THIS_IP=${HOST_2}
  23. etcd --data-dir=data.etcd --name ${THIS_NAME} \
  24. --initial-advertise-peer-urls http://${THIS_IP}:2380 \
  25. --listen-peer-urls http://${THIS_IP}:2380 \
  26. --advertise-client-urls http://${THIS_IP}:2379 \
  27. --listen-client-urls http://${THIS_IP}:2379 \
  28. --initial-cluster ${CLUSTER} \
  29. --initial-cluster-state ${CLUSTER_STATE} \
  30. --initial-cluster-token ${TOKEN}
  31. # For node 3
  32. THIS_NAME=${NAME_3}
  33. THIS_IP=${HOST_3}
  34. etcd --data-dir=data.etcd --name ${THIS_NAME} \
  35. --initial-advertise-peer-urls http://${THIS_IP}:2380 \
  36. --listen-peer-urls http://${THIS_IP}:2380 \
  37. --advertise-client-urls http://${THIS_IP}:2379 \
  38. --listen-client-urls http://${THIS_IP}:2379 \
  39. --initial-cluster ${CLUSTER} \
  40. --initial-cluster-state ${CLUSTER_STATE} \
  41. --initial-cluster-token ${TOKEN}

Then replace a member with member remove and member add commands:

  1. # get member ID
  2. export ETCDCTL_API=3
  3. HOST_1=10.240.0.13
  4. HOST_2=10.240.0.14
  5. HOST_3=10.240.0.15
  6. etcdctl --endpoints=${HOST_1}:2379,${HOST_2}:2379,${HOST_3}:2379 member list
  7. # remove the member
  8. MEMBER_ID=278c654c9a6dfd3b
  9. etcdctl --endpoints=${HOST_1}:2379,${HOST_2}:2379,${HOST_3}:2379 \
  10. member remove ${MEMBER_ID}
  11. # add a new member (node 4)
  12. export ETCDCTL_API=3
  13. NAME_1=etcd-node-1
  14. NAME_2=etcd-node-2
  15. NAME_4=etcd-node-4
  16. HOST_1=10.240.0.13
  17. HOST_2=10.240.0.14
  18. HOST_4=10.240.0.16 # new member
  19. etcdctl --endpoints=${HOST_1}:2379,${HOST_2}:2379 \
  20. member add ${NAME_4} \
  21. --peer-urls=http://${HOST_4}:2380

Next, start the new member with --initial-cluster-state existing flag:

  1. # [WARNING] If the new member starts from the same disk space,
  2. # make sure to remove the data directory of the old member
  3. #
  4. # restart with 'existing' flag
  5. TOKEN=my-etcd-token-1
  6. CLUSTER_STATE=existing
  7. NAME_1=etcd-node-1
  8. NAME_2=etcd-node-2
  9. NAME_4=etcd-node-4
  10. HOST_1=10.240.0.13
  11. HOST_2=10.240.0.14
  12. HOST_4=10.240.0.16 # new member
  13. CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_4}=http://${HOST_4}:2380
  14. THIS_NAME=${NAME_4}
  15. THIS_IP=${HOST_4}
  16. etcd --data-dir=data.etcd --name ${THIS_NAME} \
  17. --initial-advertise-peer-urls http://${THIS_IP}:2380 \
  18. --listen-peer-urls http://${THIS_IP}:2380 \
  19. --advertise-client-urls http://${THIS_IP}:2379 \
  20. --listen-client-urls http://${THIS_IP}:2379 \
  21. --initial-cluster ${CLUSTER} \
  22. --initial-cluster-state ${CLUSTER_STATE} \

Auth

auth,user,role for authentication: