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 ```