go.etcd.io/etcd@v3.3.27+incompatible/contrib/systemd/etcd2-backup-coreos/README.md (about)

     1  # etcd2-backup-coreos
     2  
     3  Remote backup and multi-node restore services for etcd2 clusters on CoreOS Linux.
     4  
     5  **Warning:** This package is only intended for use on CoreOS Linux.
     6  
     7  ## Terminology
     8  
     9  **Founding member** : The node which is the first member of the new recovered cluster. It is this node's rclone backup data (only) that will be used to restore the cluster. The rest of the nodes will join the cluster with no data, and simply catch up with the **founding member**.
    10  
    11  ## Configuration
    12  
    13  Before installing etcd2-backup, configure `30-etcd2-backup-restore.conf`:
    14  
    15  ```
    16  [Service]
    17  Environment="ETCD_RESTORE_MASTER_ADV_PEER_URLS=<http://host:port>"
    18  Environment="RCLONE_ENDPOINT=remote-name:path/to/backups"
    19  ```
    20  
    21  Assuming a deployment to CoreOS with etcd2, only change:
    22  
    23  * `ETCD_RESTORE_MASTER_ADV_PEER_URLS`
    24     This is the new advertised peer url of the new etcd2 node that will be the founding member of the new restored cluster. We will call this node the **founding member**.
    25  
    26  *  `RCLONE_ENDPOINT`
    27      The rclone endpoint to which backups will be stored.
    28  
    29      Feel free to point any number of machines at the same RCLONE_ENDPOINT, path and all. Backups for each machine are stored in a sub-folder named with the machine ID (%m in systemd parlance)
    30  
    31  *  `./rclone.conf`
    32      The rclone configuration file which will be installed. Must list a `[section]` which matches `RCLONE_ENDPOINT`'s remote-name component.
    33  
    34      An easy way to generate this config file is to [install rclone](http://rclone.org/install/) on a local machine. Then follow the [configuration instructions](http://rclone.org/docs/) to generate an `rclone.conf` file.
    35  
    36  To adjust backup frequency, edit `./etcd2-backup.timer`
    37  
    38  ## Installation
    39  
    40  Once those things are configured, run `./build`.
    41  
    42  The `build` script generates a tarball for copying to CoreOS instances. The tarball contains the `etcd2-backup-install` script.
    43  
    44  After extracting the contents of the tar file and running the install script, three new systemd services are added. One service, `etcd2-backup`, performs periodic etcd backups, while the other two services, `etcd2-restore` and `etcd2-join`, handle restore procedures.
    45  
    46  * `etcd2-backup.service`
    47     A oneshot service which calls `etcdctl backup` and syncs the backups to the rclone endpoint (using an rclone container, of course). `etcd2-backup.timer` is responsible for periodically running this service.
    48  
    49  * `etcd2-restore.service`
    50      A oneshot service which wipes all etcd2 data and restores a single-node cluster from the rclone backup. This is for restoring the **founding member** only.
    51  
    52  * `etcd2-join.service`
    53     A oneshot service which wipes all etcd2 data and re-joins the new cluster. This is for adding members **after** the **founding member** has succesfully established the new cluster via `etcd2-restore.service`
    54  
    55  ## Recovery
    56  
    57  This assumes that the cluster has lost quorum and is not recoverable. Otherwise try to heal the cluster first.
    58  
    59  ### Backup Freshness
    60  
    61  Two factors contribute to the relative freshness or staleness of a backup. The `etcd2-backup.timer` takes a backup every 30 seconds by default, and the etcd `snapshot-count` option controls how many transactions are committed between each write of the snapshot to permanent storage. Given those parameters, we can compute the upper bound on the outdatedness of a backup.
    62  Assumptions:
    63  * transaction rate is a constant `1000 transactions / second`
    64  * `etcd2-backup.timer` is configured for a 30 second interval
    65  * `etcd2 snapshot-count=10000`
    66  
    67  ```
    68  max-missed-seconds= (10000 transactions / (1000 transactions / second)) + 30 seconds = 40 seconds
    69  ```
    70  
    71  ### Recovery Procedure
    72  
    73  1. Make sure `etcd2.service` and `etcd2-backup.timer` are stopped on all nodes in the cluster
    74  
    75  2. Restore the **founding member** by starting `etcd2-restore.service` and then, if successful, `etcd2.service`
    76  
    77  3. Restore the rest of the cluster **one at a time**. Start `etcd2-join.service`, and then, if successful, `etcd2.service`. Please verify with `etcdctl cluster-health` that the expected set of nodes is present and healthy after each node joins.
    78  
    79  4. Verify that the data is sane (enough). If so, kick off `etcd2-backup.timer` on all nodes and, hopefully, go back to bed.
    80  
    81  ## Retroactively change the founding member
    82  
    83  It is necessary to change the cluster's founding member in order to restore a cluster from any other node's data.
    84  
    85  Change the value of `ETCD_RESTORE_MASTER_ADV_PEER_URLS` in `30-etcd2-backup-restore.conf` to the advertised peer url of the new founding member. Repeat the install process above on all nodes in the cluster, then proceed with the [recovery procedure](README.md#recovery-procedure).
    86  
    87  ## Example
    88  
    89  Let's pretend that we have an initial 3 node CoreOS cluster that we want to back up to S3.
    90  
    91  
    92  | ETCD_NAME  | ETCD_ADVERTISED_PEER_URL |
    93  | ------------- |:-------------:|
    94  | e1   | http://172.17.4.51:2379 |
    95  | e2   | http://172.17.4.52:2379 |
    96  | e3   | http://172.17.4.53:2379 |
    97  
    98  In the event that the cluster fails, we want to restore from `e1`'s backup
    99  
   100  ## Configuration
   101  
   102  ```
   103  [Service]
   104  Environment="ETCD_RESTORE_MASTER_ADV_PEER_URLS=http://172.17.4.51:2379"
   105  Environment="RCLONE_ENDPOINT=s3-testing-conf:s3://etcd2-backup-bucket/backups"
   106  ```
   107  
   108  The `./rclone.conf` file must contain a `[section]` matching `RCLONE_ENDPOINTS`'s remote-name component.
   109  
   110  ```
   111  [s3-testing-conf]
   112  type = s3
   113  access_key_id = xxxxxxxx
   114  secret_access_key = xxxxxx
   115  region = us-west-1
   116  endpoint =
   117  location_constraint =
   118  ```
   119  
   120  ## Installation
   121  
   122  ```sh
   123  cd etcd2-backup
   124  ./build
   125  scp etcd2-backup.tgz core@e1:~/
   126  ssh core@e1
   127  e1 $  mkdir -p ~/etcd2-backup
   128  e1 $  mv etcd2-backup.tgz etcd2-backup/
   129  e1 $ cd etcd2-backup
   130  e1 $ tar zxvf ~/etcd2-backup.tgz
   131  e1 $ ./etcd2-backup-install
   132  # Only do the following two commands if this node should generate backups
   133  e1 $ sudo systemctl enable etcd2-backup.timer
   134  e1 $ sudo systemctl start etcd2-backup.timer
   135  
   136  e1 $ exit
   137  ```
   138  
   139  Now `e1`'s etcd data will be backed up to `s3://etcd2-backup-bucket/backups/<e1-machine-id>/` according to the schedule described in `etcd2-backup.timer`.
   140  
   141  Repeat the process for `e2` and `e3`. To stop a node from generating backups, omit enabling and starting `etcd2-backup.timer`.
   142  
   143  ## Restore the cluster
   144  
   145  Let's assume that a mischievous friend decided it would be a good idea to corrupt the etcd2 data-dir on ALL of the nodes (`e1`,`e2`,`e3`). Simply restore the cluster from `e1`'s backup.
   146  
   147  Here's how to recover:
   148  
   149  ```sh
   150  # First, ENSURE etcd2 and etcd2-backup are not running on any nodes
   151  for node in e{1..3};do
   152      ssh core@$node "sudo systemctl stop etcd2.service etcd2-backup.{timer,service}"
   153  done
   154  
   155  ssh core@e1 "sudo systemctl start etcd2-restore.service && sudo systemctl start etcd2.service"
   156  
   157  for node in e{2..3};do
   158      ssh core@$node "sudo systemctl start etcd2-join.service && sudo systemctl start etcd2.service"
   159      sleep 10
   160  done
   161  ```
   162  
   163  After e2 and e3 finish catching up, the cluster should be back to normal.
   164  
   165  ## Migrate the cluster
   166  
   167  The same friend who corrupted the etcd2 data-dirs decided that to have more fun. This time, the friend dumps coffee on the machines hosting `e1`, `e2` and `e3`. There is a horrible smell, and the machines are dead.
   168  
   169  Luckily, there's a new 3-node etcd2 cluster ready to go, along with the S3 backup for `e1` from the old cluster.
   170  
   171  The new cluster configuration looks like this. Assume that etcd2-backup is not installed. (If it is, make sure it's not running on any nodes)
   172  
   173  | ETCD_NAME  | ETCD_ADVERTISED_PEER_URL |
   174  | ------------- |:-------------:|
   175  | q1   | http://172.17.8.201:2379 |
   176  | q2   | http://172.17.8.202:2379 |
   177  | q3   | http://172.17.8.203:2379 |
   178  
   179  We will assume `q1` is the chosen founding member, though picking any node is fine.
   180  
   181  ## Migrate the remote backup
   182  
   183  First, copy the backup from `e1`'s backup folder to `q1`'s backup folder. I will show the S3 example.
   184  
   185  ```sh
   186  # Make sure to remove q1's backup directory, if it exists already
   187  aws s3 rm --recursive s3://etcd2-backup-bucket/backups/<q1-machine-id>
   188  aws s3 cp --recursive s3://etcd2-backup-bucket/backups/<e1-machine-id> s3://etcd2-backup-bucket/backups/<q1-machine-id>
   189  ```
   190  
   191  ## Configure the New Cluster
   192  
   193  ```
   194  [Service]
   195  Environment="ETCD_RESTORE_MASTER_ADV_PEER_URLS=http://172.17.8.201:2379"
   196  Environment="RCLONE_ENDPOINT=s3-testing-conf:s3://etcd2-backup-bucket/backups"
   197  ```
   198  
   199  Since this is a new cluster, each new node will have a new `machine-id` and will not clobber the backups from the old cluster, even though `RCLONE_ENDPOINT` is the same for both the old `e` cluster and the new `q` cluster.
   200  
   201  ## Installation
   202  
   203  We first want to install the configured etcd2-backup package on all nodes, but not start any services yet.
   204  
   205  ```sh
   206  cd etcd2-backup
   207  ./build
   208  for node in q{1..3};do
   209      scp etcd2-backup.tgz core@$node:~/
   210      ssh core@$node "mkdir -p ~/etcd2-backup"
   211      ssh core@$node "mv etcd2-backup.tgz etcd2-backup/"
   212      ssh core@$node " cd etcd2-backup"
   213      ssh core@$node " tar zxvf ~/etcd2-backup.tgz"
   214      ssh core@$node " ./etcd2-backup-install"
   215  done
   216  ```
   217  
   218  ## Migrate the Cluster
   219  
   220  With `q1` as the founding member.
   221  
   222  ```sh
   223  # First, make SURE etcd2 and etcd2-backup are not running on any nodes
   224  
   225  for node in q{1..3};do
   226      ssh core@$node "sudo systemctl stop etcd2.service"
   227  done
   228  
   229  ssh core@q1 "sudo systemctl start etcd2-restore.service && sudo systemctl start etcd2.service"
   230  
   231  for node in q{2..3};do
   232      ssh core@$node "sudo systemctl start etcd2-join.service && sudo systemctl start etcd2.service"
   233      sleep 10
   234  done
   235  ```
   236  
   237  After confirming the cluster has migrated properly, start and enable `etcd2-backup.timer` on at least one node.
   238  
   239  ```sh
   240  ssh core@q1 "sudo systemctl enable etcd2-backup.service && sudo systemctl start etcd2-backup.service"
   241  ```
   242  
   243  There should now be periodic backups going to: `s3://etcd2-backup-bucket/backups/<q1-machine-id>`
   244  
   245  ## Words of caution
   246  
   247  1. Notice the `sleep 10` commands that follow starting `etcd2-join.service` and then `etcd2.service`. This sleep is there to allow the member that joined to cluster time to catch up on the cluster state before we attempt to add the next member. This involves sending the entire snapshot over the network. If the dataset is large, the network between nodes is slow, disks are already bogged down, or the system is otherwise overutilized, try increasing the sleep.
   248  
   249     In the case of large data sets, it is recommended to copy the data directory produced by `etcd2-restore` on the founding member to the other nodes before running `etcd2-join` on them. This will avoid etcd transferring the entire snapshot to every node after it joins the cluster.
   250  
   251  2. It is not recommended clients be allowed to access the etcd2 cluster **until** all members have been added and finished catching up.