From 6956ed457ba1e1c2890a12ca0ec5d5e1fa83664d Mon Sep 17 00:00:00 2001 From: Hongchao Deng Date: Fri, 7 Oct 2016 16:43:30 -0700 Subject: [PATCH] doc: upgrade design --- design/cluster_upgrade.md | 33 +++++++++++++++++++++++++++++---- design/upgrade_diagram.jpg | Bin 0 -> 31686 bytes 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 design/upgrade_diagram.jpg diff --git a/design/cluster_upgrade.md b/design/cluster_upgrade.md index c0af9e0..4fc525a 100644 --- a/design/cluster_upgrade.md +++ b/design/cluster_upgrade.md @@ -1,10 +1,35 @@ # Cluster upgrade -- etcd supports rolling upgrade from one minor release version to its next minor release version. For example, we can directly upgrade etcd 3.0.7 to 3.1.0. -- etcd supports rolling upgrade within one minor release. For example, we can upgrade etcd 3.0.1 to 3.0.7. -- etcd supports minor version upgrade unconcerned with patch version, e.g. from 3.0.1 to 3.1.0. Nonetheless it's recommended to upgrade from 3.0.1 to 3.0.n (n is latest) and then from 3.0.n to 3.1.0. +## etcd upgrade story + +- A user “kubectl apply” a new version in EtcdCluster object +- etcd controller detects the version and + - if the targeted version is allowed, does rolling upgrade + - otherwise, rejects it in admission control; We will write an admission plug-in to verify EtcdCluster object. + +## Diagram +![](./upgrade_diagram.jpg) ## Rolling upgrade -We upgrade one member at a time during a cluster upgrade. To upgrade that member, we simply update the pod manifest with the desired version of etcd container. We need to clear all --initial prefix flags previously set. +- We have an annotation key for the version of etcd cluster +- During upgrade, we will list pods of this cluster, and differentiate them by two versions. Then do + - if num(old) + num(new) == total, we will try to scale down old by 1, scale up new by 1; + Note that some ops might fail and lead to situation num(old) + num(new) != total + - if num(old) + num(new) < total, we will try to scale up new by 1 + - if num(old) + num(new) > total, we will try to scale down old by 1 +- Repeat until num(old) == 0 && num(new) >= total; if num(new) > total, it falls to normal reconcile path. +## Support notes + +- Upgrade path: We only support one minor version upgrade, e.g. 3.0 -> 3.1, no 3.0 -> 3.2. Only support v3.0+ +- Rollback: We relies on etcd controller to do periodic backup. + For alpha release, we will provide features to do manual rollback. + In the future, we might consider support automatic rollback. + + +## etcd upgrade policy + +- etcd supports rolling upgrade from one minor release version to its next minor release version. For example, we can directly upgrade etcd 3.0.7 to 3.1.0. +- etcd supports rolling upgrade within one minor release. For example, we can upgrade etcd 3.0.1 to 3.0.7. +- etcd supports minor version upgrade unconcerned with patch version, e.g. from 3.0.1 to 3.1.0. Nonetheless it's recommended to upgrade from 3.0.1 to 3.0.n (n is latest) and then from 3.0.n to 3.1.0. \ No newline at end of file diff --git a/design/upgrade_diagram.jpg b/design/upgrade_diagram.jpg new file mode 100644 index 0000000000000000000000000000000000000000..35e75cd4acf35ab6aee918f6b9220586afe82f1e GIT binary patch literal 31686 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