Demo

    This series of examples shows the basic procedures for working with an etcd cluster.

    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:

    10_etcdctl_endpoint_2016050501

    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 can only be requested from one etcd node, so --endpoints flag should contain only one endpoint.

    1. ENDPOINTS=$HOST_1:2379
    2. etcdctl --endpoints=$ENDPOINTS snapshot save my.db
    3. 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:

    12_etcdctl_migrate_2016061602

    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:

    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. THIS_NAME=${NAME_1}
    11. THIS_IP=${HOST_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} \
    23. --initial-cluster-token ${TOKEN}

    Auth

    auth,,role for authentication:

    14_etcdctl_auth_2016062301