go.etcd.io/etcd@v3.3.27+incompatible/Documentation/demo.md (about)

     1  ---
     2  title: Demo
     3  ---
     4  
     5  This series of examples shows the basic procedures for working with an etcd cluster.
     6  
     7  ## Set up a cluster
     8  
     9  <img src="https://storage.googleapis.com/etcd/demo/01_etcd_clustering_2016051001.gif" alt="01_etcd_clustering_2016050601"/>
    10  
    11  On each etcd node, specify the cluster members:
    12  
    13  ```
    14  TOKEN=token-01
    15  CLUSTER_STATE=new
    16  NAME_1=machine-1
    17  NAME_2=machine-2
    18  NAME_3=machine-3
    19  HOST_1=10.240.0.17
    20  HOST_2=10.240.0.18
    21  HOST_3=10.240.0.19
    22  CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380
    23  ```
    24  
    25  Run this on each machine:
    26  
    27  ```
    28  # For machine 1
    29  THIS_NAME=${NAME_1}
    30  THIS_IP=${HOST_1}
    31  etcd --data-dir=data.etcd --name ${THIS_NAME} \
    32  	--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
    33  	--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
    34  	--initial-cluster ${CLUSTER} \
    35  	--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
    36  
    37  # For machine 2
    38  THIS_NAME=${NAME_2}
    39  THIS_IP=${HOST_2}
    40  etcd --data-dir=data.etcd --name ${THIS_NAME} \
    41  	--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
    42  	--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
    43  	--initial-cluster ${CLUSTER} \
    44  	--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
    45  
    46  # For machine 3
    47  THIS_NAME=${NAME_3}
    48  THIS_IP=${HOST_3}
    49  etcd --data-dir=data.etcd --name ${THIS_NAME} \
    50  	--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
    51  	--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
    52  	--initial-cluster ${CLUSTER} \
    53  	--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
    54  ```
    55  
    56  Or use our public discovery service:
    57  
    58  ```
    59  curl https://discovery.etcd.io/new?size=3
    60  https://discovery.etcd.io/a81b5818e67a6ea83e9d4daea5ecbc92
    61  
    62  # grab this token
    63  TOKEN=token-01
    64  CLUSTER_STATE=new
    65  NAME_1=machine-1
    66  NAME_2=machine-2
    67  NAME_3=machine-3
    68  HOST_1=10.240.0.17
    69  HOST_2=10.240.0.18
    70  HOST_3=10.240.0.19
    71  DISCOVERY=https://discovery.etcd.io/a81b5818e67a6ea83e9d4daea5ecbc92
    72  
    73  THIS_NAME=${NAME_1}
    74  THIS_IP=${HOST_1}
    75  etcd --data-dir=data.etcd --name ${THIS_NAME} \
    76  	--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
    77  	--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
    78  	--discovery ${DISCOVERY} \
    79  	--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
    80  
    81  THIS_NAME=${NAME_2}
    82  THIS_IP=${HOST_2}
    83  etcd --data-dir=data.etcd --name ${THIS_NAME} \
    84  	--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
    85  	--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
    86  	--discovery ${DISCOVERY} \
    87  	--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
    88  
    89  THIS_NAME=${NAME_3}
    90  THIS_IP=${HOST_3}
    91  etcd --data-dir=data.etcd --name ${THIS_NAME} \
    92  	--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
    93  	--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
    94  	--discovery ${DISCOVERY} \
    95  	--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
    96  ```
    97  
    98  Now etcd is ready! To connect to etcd with etcdctl:
    99  
   100  ```
   101  export ETCDCTL_API=3
   102  HOST_1=10.240.0.17
   103  HOST_2=10.240.0.18
   104  HOST_3=10.240.0.19
   105  ENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379
   106  
   107  etcdctl --endpoints=$ENDPOINTS member list
   108  ```
   109  
   110  
   111  ## Access etcd
   112  
   113  <img src="https://storage.googleapis.com/etcd/demo/02_etcdctl_access_etcd_2016051001.gif" alt="02_etcdctl_access_etcd_2016051001"/>
   114  
   115  `put` command to write:
   116  
   117  ```
   118  etcdctl --endpoints=$ENDPOINTS put foo "Hello World!"
   119  ```
   120  
   121  `get` to read from etcd:
   122  
   123  ```
   124  etcdctl --endpoints=$ENDPOINTS get foo
   125  etcdctl --endpoints=$ENDPOINTS --write-out="json" get foo
   126  ```
   127  
   128  
   129  ## Get by prefix
   130  
   131  <img src="https://storage.googleapis.com/etcd/demo/03_etcdctl_get_by_prefix_2016050501.gif" alt="03_etcdctl_get_by_prefix_2016050501"/>
   132  
   133  ```
   134  etcdctl --endpoints=$ENDPOINTS put web1 value1
   135  etcdctl --endpoints=$ENDPOINTS put web2 value2
   136  etcdctl --endpoints=$ENDPOINTS put web3 value3
   137  
   138  etcdctl --endpoints=$ENDPOINTS get web --prefix
   139  ```
   140  
   141  
   142  ## Delete
   143  
   144  <img src="https://storage.googleapis.com/etcd/demo/04_etcdctl_delete_2016050601.gif" alt="04_etcdctl_delete_2016050601"/>
   145  
   146  ```
   147  etcdctl --endpoints=$ENDPOINTS put key myvalue
   148  etcdctl --endpoints=$ENDPOINTS del key
   149  
   150  etcdctl --endpoints=$ENDPOINTS put k1 value1
   151  etcdctl --endpoints=$ENDPOINTS put k2 value2
   152  etcdctl --endpoints=$ENDPOINTS del k --prefix
   153  ```
   154  
   155  
   156  ## Transactional write
   157  
   158  `txn` to wrap multiple requests into one transaction:
   159  
   160  <img src="https://storage.googleapis.com/etcd/demo/05_etcdctl_transaction_2016050501.gif" alt="05_etcdctl_transaction_2016050501"/>
   161  
   162  ```
   163  etcdctl --endpoints=$ENDPOINTS put user1 bad
   164  etcdctl --endpoints=$ENDPOINTS txn --interactive
   165  
   166  compares:
   167  value("user1") = "bad"      
   168  
   169  success requests (get, put, delete):
   170  del user1  
   171  
   172  failure requests (get, put, delete):
   173  put user1 good
   174  ```
   175  
   176  
   177  ## Watch
   178  
   179  `watch` to get notified of future changes:
   180  
   181  <img src="https://storage.googleapis.com/etcd/demo/06_etcdctl_watch_2016050501.gif" alt="06_etcdctl_watch_2016050501"/>
   182  
   183  ```
   184  etcdctl --endpoints=$ENDPOINTS watch stock1
   185  etcdctl --endpoints=$ENDPOINTS put stock1 1000
   186  
   187  etcdctl --endpoints=$ENDPOINTS watch stock --prefix
   188  etcdctl --endpoints=$ENDPOINTS put stock1 10
   189  etcdctl --endpoints=$ENDPOINTS put stock2 20
   190  ```
   191  
   192  
   193  ## Lease
   194  
   195  `lease` to write with TTL:
   196  
   197  <img src="https://storage.googleapis.com/etcd/demo/07_etcdctl_lease_2016050501.gif" alt="07_etcdctl_lease_2016050501"/>
   198  
   199  ```
   200  etcdctl --endpoints=$ENDPOINTS lease grant 300
   201  # lease 2be7547fbc6a5afa granted with TTL(300s)
   202  
   203  etcdctl --endpoints=$ENDPOINTS put sample value --lease=2be7547fbc6a5afa
   204  etcdctl --endpoints=$ENDPOINTS get sample
   205  
   206  etcdctl --endpoints=$ENDPOINTS lease keep-alive 2be7547fbc6a5afa
   207  etcdctl --endpoints=$ENDPOINTS lease revoke 2be7547fbc6a5afa
   208  # or after 300 seconds
   209  etcdctl --endpoints=$ENDPOINTS get sample
   210  ```
   211  
   212  
   213  ## Distributed locks
   214  
   215  `lock` for distributed lock:
   216  
   217  <img src="https://storage.googleapis.com/etcd/demo/08_etcdctl_lock_2016050501.gif" alt="08_etcdctl_lock_2016050501"/>
   218  
   219  ```
   220  etcdctl --endpoints=$ENDPOINTS lock mutex1
   221  
   222  # another client with the same name blocks
   223  etcdctl --endpoints=$ENDPOINTS lock mutex1
   224  ```
   225  
   226  
   227  ## Elections
   228  
   229  `elect` for leader election:
   230  
   231  <img src="https://storage.googleapis.com/etcd/demo/09_etcdctl_elect_2016050501.gif" alt="09_etcdctl_elect_2016050501"/>
   232  
   233  ```
   234  etcdctl --endpoints=$ENDPOINTS elect one p1
   235  
   236  # another client with the same name blocks
   237  etcdctl --endpoints=$ENDPOINTS elect one p2
   238  ```
   239  
   240  
   241  ## Cluster status
   242  
   243  Specify the initial cluster configuration for each machine:
   244  
   245  <img src="https://storage.googleapis.com/etcd/demo/10_etcdctl_endpoint_2016050501.gif" alt="10_etcdctl_endpoint_2016050501"/>
   246  
   247  ```
   248  etcdctl --write-out=table --endpoints=$ENDPOINTS endpoint status
   249  
   250  +------------------+------------------+---------+---------+-----------+-----------+------------+
   251  |     ENDPOINT     |        ID        | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
   252  +------------------+------------------+---------+---------+-----------+-----------+------------+
   253  | 10.240.0.17:2379 | 4917a7ab173fabe7 | 3.0.0   | 45 kB   | true      |         4 |      16726 |
   254  | 10.240.0.18:2379 | 59796ba9cd1bcd72 | 3.0.0   | 45 kB   | false     |         4 |      16726 |
   255  | 10.240.0.19:2379 | 94df724b66343e6c | 3.0.0   | 45 kB   | false     |         4 |      16726 |
   256  +------------------+------------------+---------+---------+-----------+-----------+------------+
   257  ```
   258  
   259  ```
   260  etcdctl --endpoints=$ENDPOINTS endpoint health
   261  
   262  10.240.0.17:2379 is healthy: successfully committed proposal: took = 3.345431ms
   263  10.240.0.19:2379 is healthy: successfully committed proposal: took = 3.767967ms
   264  10.240.0.18:2379 is healthy: successfully committed proposal: took = 4.025451ms
   265  ```
   266  
   267  
   268  ## Snapshot
   269  
   270  `snapshot` to save point-in-time snapshot of etcd database:
   271  
   272  <img src="https://storage.googleapis.com/etcd/demo/11_etcdctl_snapshot_2016051001.gif" alt="11_etcdctl_snapshot_2016051001"/>
   273  
   274  ```
   275  etcdctl --endpoints=$ENDPOINTS snapshot save my.db
   276  
   277  Snapshot saved at my.db
   278  ```
   279  
   280  ```
   281  etcdctl --write-out=table --endpoints=$ENDPOINTS snapshot status my.db
   282  
   283  +---------+----------+------------+------------+
   284  |  HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
   285  +---------+----------+------------+------------+
   286  | c55e8b8 |        9 |         13 | 25 kB      |
   287  +---------+----------+------------+------------+
   288  ```
   289  
   290  
   291  ## Migrate
   292  
   293  `migrate` to transform etcd v2 to v3 data:
   294  
   295  <img src="https://storage.googleapis.com/etcd/demo/12_etcdctl_migrate_2016061602.gif" alt="12_etcdctl_migrate_2016061602"/>
   296  
   297  ```
   298  # write key in etcd version 2 store
   299  export ETCDCTL_API=2
   300  etcdctl --endpoints=http://$ENDPOINT set foo bar
   301  
   302  # read key in etcd v2
   303  etcdctl --endpoints=$ENDPOINTS --output="json" get foo
   304  
   305  # stop etcd node to migrate, one by one
   306  
   307  # migrate v2 data
   308  export ETCDCTL_API=3
   309  etcdctl --endpoints=$ENDPOINT migrate --data-dir="default.etcd" --wal-dir="default.etcd/member/wal"
   310  
   311  # restart etcd node after migrate, one by one
   312  
   313  # confirm that the key got migrated
   314  etcdctl --endpoints=$ENDPOINTS get /foo
   315  ```
   316  
   317  
   318  ## Member
   319  
   320  `member` to add,remove,update membership:
   321  
   322  <img src="https://storage.googleapis.com/etcd/demo/13_etcdctl_member_2016062301.gif" alt="13_etcdctl_member_2016062301"/>
   323  
   324  ```
   325  # For each machine
   326  TOKEN=my-etcd-token-1
   327  CLUSTER_STATE=new
   328  NAME_1=etcd-node-1
   329  NAME_2=etcd-node-2
   330  NAME_3=etcd-node-3
   331  HOST_1=10.240.0.13
   332  HOST_2=10.240.0.14
   333  HOST_3=10.240.0.15
   334  CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380
   335  
   336  # For node 1
   337  THIS_NAME=${NAME_1}
   338  THIS_IP=${HOST_1}
   339  etcd --data-dir=data.etcd --name ${THIS_NAME} \
   340  	--initial-advertise-peer-urls http://${THIS_IP}:2380 \
   341  	--listen-peer-urls http://${THIS_IP}:2380 \
   342  	--advertise-client-urls http://${THIS_IP}:2379 \
   343  	--listen-client-urls http://${THIS_IP}:2379 \
   344  	--initial-cluster ${CLUSTER} \
   345  	--initial-cluster-state ${CLUSTER_STATE} \
   346  	--initial-cluster-token ${TOKEN}
   347  
   348  # For node 2
   349  THIS_NAME=${NAME_2}
   350  THIS_IP=${HOST_2}
   351  etcd --data-dir=data.etcd --name ${THIS_NAME} \
   352  	--initial-advertise-peer-urls http://${THIS_IP}:2380 \
   353  	--listen-peer-urls http://${THIS_IP}:2380 \
   354  	--advertise-client-urls http://${THIS_IP}:2379 \
   355  	--listen-client-urls http://${THIS_IP}:2379 \
   356  	--initial-cluster ${CLUSTER} \
   357  	--initial-cluster-state ${CLUSTER_STATE} \
   358  	--initial-cluster-token ${TOKEN}
   359  
   360  # For node 3
   361  THIS_NAME=${NAME_3}
   362  THIS_IP=${HOST_3}
   363  etcd --data-dir=data.etcd --name ${THIS_NAME} \
   364  	--initial-advertise-peer-urls http://${THIS_IP}:2380 \
   365  	--listen-peer-urls http://${THIS_IP}:2380 \
   366  	--advertise-client-urls http://${THIS_IP}:2379 \
   367  	--listen-client-urls http://${THIS_IP}:2379 \
   368  	--initial-cluster ${CLUSTER} \
   369  	--initial-cluster-state ${CLUSTER_STATE} \
   370  	--initial-cluster-token ${TOKEN}
   371  ```
   372  
   373  Then replace a member with `member remove` and `member add` commands:
   374  
   375  ```
   376  # get member ID
   377  export ETCDCTL_API=3
   378  HOST_1=10.240.0.13
   379  HOST_2=10.240.0.14
   380  HOST_3=10.240.0.15
   381  etcdctl --endpoints=${HOST_1}:2379,${HOST_2}:2379,${HOST_3}:2379 member list
   382  
   383  # remove the member
   384  MEMBER_ID=278c654c9a6dfd3b
   385  etcdctl --endpoints=${HOST_1}:2379,${HOST_2}:2379,${HOST_3}:2379 \
   386  	member remove ${MEMBER_ID}
   387  
   388  # add a new member (node 4)
   389  export ETCDCTL_API=3
   390  NAME_1=etcd-node-1
   391  NAME_2=etcd-node-2
   392  NAME_4=etcd-node-4
   393  HOST_1=10.240.0.13
   394  HOST_2=10.240.0.14
   395  HOST_4=10.240.0.16 # new member
   396  etcdctl --endpoints=${HOST_1}:2379,${HOST_2}:2379 \
   397  	member add ${NAME_4} \
   398  	--peer-urls=http://${HOST_4}:2380
   399  ```
   400  
   401  Next, start the new member with `--initial-cluster-state existing` flag:
   402  
   403  ```
   404  # [WARNING] If the new member starts from the same disk space,
   405  # make sure to remove the data directory of the old member
   406  #
   407  # restart with 'existing' flag
   408  TOKEN=my-etcd-token-1
   409  CLUSTER_STATE=existing
   410  NAME_1=etcd-node-1
   411  NAME_2=etcd-node-2
   412  NAME_4=etcd-node-4
   413  HOST_1=10.240.0.13
   414  HOST_2=10.240.0.14
   415  HOST_4=10.240.0.16 # new member
   416  CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_4}=http://${HOST_4}:2380
   417  
   418  THIS_NAME=${NAME_4}
   419  THIS_IP=${HOST_4}
   420  etcd --data-dir=data.etcd --name ${THIS_NAME} \
   421  	--initial-advertise-peer-urls http://${THIS_IP}:2380 \
   422  	--listen-peer-urls http://${THIS_IP}:2380 \
   423  	--advertise-client-urls http://${THIS_IP}:2379 \
   424  	--listen-client-urls http://${THIS_IP}:2379 \
   425  	--initial-cluster ${CLUSTER} \
   426  	--initial-cluster-state ${CLUSTER_STATE} \
   427  	--initial-cluster-token ${TOKEN}
   428  ```
   429  
   430  
   431  ## Auth
   432  
   433  `auth`,`user`,`role` for authentication:
   434  
   435  <img src="https://storage.googleapis.com/etcd/demo/14_etcdctl_auth_2016062301.gif" alt="14_etcdctl_auth_2016062301"/>
   436  
   437  ```
   438  export ETCDCTL_API=3
   439  ENDPOINTS=localhost:2379
   440  
   441  etcdctl --endpoints=${ENDPOINTS} role add root
   442  etcdctl --endpoints=${ENDPOINTS} role grant-permission root readwrite foo
   443  etcdctl --endpoints=${ENDPOINTS} role get root
   444  
   445  etcdctl --endpoints=${ENDPOINTS} user add root
   446  etcdctl --endpoints=${ENDPOINTS} user grant-role root root
   447  etcdctl --endpoints=${ENDPOINTS} user get root
   448  
   449  etcdctl --endpoints=${ENDPOINTS} auth enable
   450  # now all client requests go through auth
   451  
   452  etcdctl --endpoints=${ENDPOINTS} --user=root:123 put foo bar
   453  etcdctl --endpoints=${ENDPOINTS} get foo
   454  etcdctl --endpoints=${ENDPOINTS} --user=root:123 get foo
   455  etcdctl --endpoints=${ENDPOINTS} --user=root:123 get foo1
   456  ```