kubespray での Kubernetes クラスタ アップグレード

## はじめに
kubespray で構築した kubernetes クラスタの Upgrade (`v1.16.3` -> `v1.19.3`) を実施したのでその内容を記載する

### 2021.11.13 追記
Upgrade (`v1.19.3` -> `v1.21.6`) を追記

## 実施環境
下記で構築した環境, バージョン

Qiita: [kubespray での kubernetes クラスタ構築メモ](https://qiita.com/suzuyui/items/e7531fe5e1e84c061b23)

Kubespray : `v2.12.0`
Kubernets : `v1.16.3`

## kubespray での Upgrade 方法

[github の upgrade.md](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/upgrades.md) を読むと 2通り

- [安全でない方法](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/upgrades.md#unsafe-upgrade-example)
    - `cluster.yml` で `-e` で `kube_version` を指定して、`upgrade_cluster_setup=true` を設定する
        - 例： ansible-playbook cluster.yml -i inventory/sample/hosts.ini -e kube_version=v1.4.3 -e upgrade_cluster_setup=true
- [グレースフルアップグレード](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/upgrades.md#graceful-upgrade)
    - `upgrade-cluster.yml` で `-e` で `kube_version`で指定してアップグレードする
        - 例： ansible-playbook upgrade-cluster.yml -b -i inventory/sample/hosts.ini -e kube_version=v1.6.0

※`-e`を使わないとデフォルトのバージョンになる

また、[**kubespray の version(tag) はスキップできない**](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/upgrades.md#multiple-upgrades)ので徐々にアップグレードする必要がある

kubespray tag `v2.12.0` から tag `v2.14.0` を使ってアップグレードは `v2.12.0` -> `v2.13.0` -> `v2.14.0` のようにする必要がある

今回の作業では`upgrade-cluster.yml`を使用したアップグレードを実施する

## kubespray の Kubernetes 対応バージョン
2020.11.21 時点で下記が対応バージョン

| Kubespray Version | Kubernets Version |
|:-:|:-:|
| v2.12.0 | v1.16.3 |
| v2.13.0 | v1.17.5 |
| v2.14.0 | v1.18.8 |
| master (v2.14.0-133-g0f7341bd) | v1.19.3 |

※ (2021.11.13追記) **master まで上げるのは良くない。[Release Version](https://github.com/kubernetes-sigs/kubespray/releases) までにする** (上記表なら正しくは v2.14.0まで)


## Upgrade 対応順番
下記の順番で Upgrade を実施・記載していく

1. hosts.yaml の準備
2. kubespray git pull
3. kubespray での kubernetes アップグレード実施
    1. v1.16.3 -> v1.17.5
    2. v1.17.5 -> v1.18.8
    3. v1.18.8 -> v1.19.3
4. その他. 作業中のエラー対応

## 1. hosts.yaml の準備
[以前の構築](https://qiita.com/suzuyui/items/e7531fe5e1e84c061b23)では inventory を INI 形式での `hosts` を作成して実施したが、このままやると途中で止まる事象を確認した。([以前のhosts例](https://qiita.com/suzuyui/items/e7531fe5e1e84c061b23#kubespray-inventory))
`hosts.yaml` 形式に書き換えたらうまくいった。
下記、実施環境での`yaml`形式の例(実施環境で利用)を記載する。

```yaml:(例)kubespray_hosts.yaml
all:
  hosts:
    k8smaster01:
      ansible_host: 192.168.129.25
      ip: 192.168.129.25
      access_ip: 192.168.129.25
    k8smaster02:
      ansible_host: 192.168.129.35
      ip: 192.168.129.35
      access_ip: 192.168.129.35
    k8smaster03:
      ansible_host: 192.168.129.26
      ip: 192.168.129.26
      access_ip: 192.168.129.26
    k8sworker01:
      ansible_host: 192.168.129.27
      ip: 192.168.129.27
      access_ip: 192.168.129.27
    k8sworker02:
      ansible_host: 192.168.129.36
      ip: 192.168.129.36
      access_ip: 192.168.129.36
    k8sworker03:
      ansible_host: 192.168.129.37
      ip: 192.168.129.37
      access_ip: 192.168.129.37
    k8scalicorr01:
      ansible_host: 192.168.129.28
      ip: 192.168.129.28
      access_ip: 192.168.129.28
    k8scalicorr02:
      ansible_host: 192.168.129.38
      ip: 192.168.129.38
      access_ip: 192.168.129.38
  children:
    kube-master:
      hosts:
        k8smaster01:
        k8smaster02:
        k8smaster03:
    kube-node:
      hosts:
        k8sworker01:
        k8sworker02:
        k8sworker03:
        k8scalicorr01:
        k8scalicorr02:
    etcd:
      hosts:
        k8smaster01:
        k8smaster02:
        k8smaster03:
    k8s-cluster:
      children:
        kube-master:
        kube-node:
        calico-rr:
    calico-rr:
      hosts:
        k8scalicorr01:
        k8scalicorr02:
    rack0:
      hosts:
        k8scalicorr01:
        k8scalicorr02:
        k8smaster01:
        k8smaster02:
        k8smaster03:
        k8sworker01:
        k8sworker02:
        k8sworker03:
      vars:
        cluster_id: "1.0.0.1"
```

※ `calico-rr` ノードは `kube-node` に入ってなくてもいいと思うが、以前構築時に組み込まれてしまったのでとりあえずそれもそのままアップグレードをするのに入れている

下記手順で使用するため、実施環境では`~/kubespray/kubespray_hosts.yaml` に保存している

## 2. kubespray git pull

アップグレード前は実施環境では`v1.16.3`となっている。(下記確認コマンド)

```sh:upgrade前get_nodes
# kubectl get nodes
NAME            STATUS   ROLES    AGE    VERSION
k8scalicorr01   Ready    <none>   339d   v1.16.3
k8scalicorr02   Ready    <none>   339d   v1.16.3
k8smaster01     Ready    master   341d   v1.16.3
k8smaster02     Ready    master   341d   v1.16.3
k8smaster03     Ready    master   341d   v1.16.3
k8sworker01     Ready    <none>   341d   v1.16.3
k8sworker02     Ready    <none>   341d   v1.16.3
k8sworker03     Ready    <none>   341d   v1.16.3
```

現状の kubespray の version を下記コマンドで確認しておく
(実施環境では kubespray を `~/kubespray`に置いている.ホームフォルダで git clone した状態)

```sh:pull前
$ cd ~/kubespray
$ git describe --tags 
v2.12.0-1-gb60ab3ae
```

kubespray の最新を pull する

```sh:gitpull
git pull
```

git pull 後のタグを確認しておく (最新タグになっている. 下記は実施時点でのtag情報)

```sh:pull後
$ git describe --tags                                             
v2.14.0-133-g0f7341bd
```

## 3. kubespray での kubernetes アップグレード実施
kubespray のバージョンごとにアップグレードが必要なので、3段階に分けて実施する
下記バージョンで実施する (下記は`kubernetes ver.`(kubespray ver.)で記載)
`v1.16.3`(v2.12) -> `v1.17.5`(v2.13.0) -> `v1.18.8`(v2.14.0) -> `v1.19.3`(master)

### 3.1. v1.16.3 -> v1.17.5

まず、kubespray の現状(実施環境)が `v2.12` なので一つ上の `v2.13.0` へ上げる

```sh
git checkout v2.13.0
```

```sh
% git describe --tags 
v2.13.0
```

pip でこの kubespray バージョンの対応バージョンへ ansible 系を上げる
(下記は`--user`で`~/.local/`にインストールする場合.全体に入れたりするなオプション不要)

```sh
pip3 install -r requirements.txt --user
```

デフォルトの group_vars などが変わっているので、inventoryフォルダを更新する
この際に、**kubespray のパラメータをデフォルト以外にしている場合**は、
`inventory/mycluster/group_vars/k8s-cluster/*.yml`内の**パラメータを更新する必要**がある(**今回は全てデフォルト値使用**. 3.2, 3.3時も同様)

```sh:inventory_group_vars等更新
cp -rp inventory/mycluster inventory/mycluster_bak
rm -Rf inventory/mycluster/   
cp -rfp inventory/sample inventory/mycluster    
cp -p kubespray_hosts.yaml inventory/mycluster/hosts.yaml
```

下記コマンドで`upgrade-cluster.yml`を使用して**クラスタアップグレード**を実施する
(環境によるが構築時同様20~40分くらいかかる)
うまくいかない場合は、下のほうに書く**作業中のエラー対応**に、実際に作業時に出た内容の対応は記載している

```sh:cluster-upgrade
ansible-playbook -i inventory/mycluster/hosts.yaml upgrade-cluster.yml -vvv --user root
```

kubectl でノードのバージョンが上がっていることを確認する

```sh:upgrade後get_nodes
# kubectl get nodes
NAME            STATUS   ROLES    AGE    VERSION
k8scalicorr01   Ready    <none>   339d   v1.17.5
k8scalicorr02   Ready    <none>   339d   v1.17.5
k8smaster01     Ready    master   341d   v1.17.5
k8smaster02     Ready    master   341d   v1.17.5
k8smaster03     Ready    master   341d   v1.17.5
k8sworker01     Ready    <none>   341d   v1.17.5
k8sworker02     Ready    <none>   341d   v1.17.5
k8sworker03     Ready    <none>   341d   v1.17.5
```

以上で、`v1.17.5`へバージョンアップ完了

### 3.2. v1.17.5 -> v1.18.8

3.1 同様下記手順でアップグレードする

```
git checkout v2.14.0
```

```
pip3 install -r requirements.txt --user
```

```sh:cluster-upgrade
ansible-playbook -i inventory/mycluster/hosts.yaml upgrade-cluster.yml -vvv --user root
```

```
# kubectl get node
NAME            STATUS   ROLES    AGE    VERSION
k8scalicorr01   Ready    <none>   339d   v1.18.8
k8scalicorr02   Ready    <none>   339d   v1.18.8
k8smaster01     Ready    master   342d   v1.18.8
k8smaster02     Ready    master   342d   v1.18.8
k8smaster03     Ready    master   342d   v1.18.8
k8sworker01     Ready    <none>   342d   v1.18.8
k8sworker02     Ready    <none>   342d   v1.18.8
k8sworker03     Ready    <none>   342d   v1.18.8
```

以上で、`v1.18.8`へバージョンアップ完了

### 3.3. v1.18.8 -> v1.19.3
※ **2021.11.13 追記： master まではアップグレードをしない方がいい (Release Version までにした方がいい)**
3.1~2 同様下記手順でアップグレードする

```
git checkout master
```

```
% git describe --tags 
v2.14.0-133-g0f7341bd
```

```
pip3 install -r requirements.txt --user
```

```sh:inventory_group_vars等更新
rm -Rf inventory/mycluster/   
cp -rfp inventory/sample inventory/mycluster    
cp -p kubespray_hosts.yaml inventory/mycluster/hosts.yaml
```

```sh:cluster-upgrade
ansible-playbook -i inventory/mycluster/hosts.yaml upgrade-cluster.yml -vvv --user root
```

```
# kubectl get node
NAME            STATUS   ROLES    AGE    VERSION
k8scalicorr01   Ready    <none>   339d   v1.19.3
k8scalicorr02   Ready    <none>   339d   v1.19.3
k8smaster01     Ready    master   342d   v1.19.3
k8smaster02     Ready    master   342d   v1.19.3
k8smaster03     Ready    master   342d   v1.19.3
k8sworker01     Ready    <none>   342d   v1.19.3
k8sworker02     Ready    <none>   342d   v1.19.3
k8sworker03     Ready    <none>   342d   v1.19.3
```

以上で、`v1.19.3`へバージョンアップ完了
**今回のアップグレード作業は完了**

### その他. 作業中のエラー対応
#### Timeout, Node status SchedulingDisabled
途中何度か Upgrade 中に Timeout して失敗した。(ノード負荷のため？何度かやるとうまくいったりした)
その際にノードが Cordon された状態になってしまったいるのがいた。
ansible-playbook が途中失敗して、`kubectl get node` で ノード STATUS が `Ready,SchedulingDisabled` となっている場合は、下記を実行する。

```sh:uncordon_対象ノードがk8smaster02というノードの場合のコマンド例
kubectl uncordon k8smaster02
```

その後に再度`ansible-playbook -i hosts.yaml upgrade-cluster.yml -vvv --user root`を実施する

#### Docker pull rate limit

docker hub は下記の通り、6時間毎に 100 コンテナとかに上限が決まっている。

[Anonymous and Free Docker Hub users are limited to 100 and 200 container image pull requests per six hours.](https://www.docker.com/increase-rate-limits)

何度か upgrade を繰り返すとこの上限に引っかかるため、このエラーにひっかかったら6時間開けないといけない。

`TASK [download : download_container | Download image if required] `

```sh:ratelimitひっかかったときのエラー表示例
TASK [download : download_container | Download image if required] *********************************************************************************************************************************************************************************************
task path: /home/xxxxx/kubespray/roles/download/tasks/download_container.yml:52
fatal: [k8sworker02 -> 192.168.129.36]: FAILED! => {
    "attempts": 4,
    "changed": true,
    "cmd": [
        "/usr/bin/docker",
        "pull",
        "docker.io/calico/node:v3.16.4"
    ],
    "delta": "0:00:02.598259",
    "end": "2020-11-21 19:18:09.155941",
    "invocation": {
        "module_args": {
            "_raw_params": "/usr/bin/docker pull docker.io/calico/node:v3.16.4",
            "_uses_shell": false,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true,
            "warn": true
        }
    },
    "msg": "non-zero return code",
    "rc": 1,
    "start": "2020-11-21 19:18:06.557682",
    "stderr": "Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit",
    "stderr_lines": [
        "Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit"
    ],
    "stdout": "",
    "stdout_lines": []
}
```

### 追記 (2021.11)
v1.19.3 -> v1.21.6 へバージョンアップをしたので、実施した内容と対応を追記する

#### kubespray の Kubernetes 対応バージョン (2021.11版)

下記が前回実施バージョン以降の 2021.11.13 時点での、Kubespray Version と、対応した Kubernetes Version

| Kubespray Version | Kubernetes Version |
|:-:|:-:|
| v2.14.0-133-g0f7341bd (現状) | v1.19.3 |
| v2.14.1 | 1.19.2/1.18.9/1.17.12 |
| v2.14.2 | v1.18.10 |
| v2.15.0 | v1.19.7 |
| v2.15.1 | v1.19.9 |
| v2.16.0 ​| v1.20.7 |
| v2.17.0 | v1.21.5 |
| v2.17.1 | v1.21.6 |

今回は、`v2.17.1` / Kubernetes: `v1.21.6` までアップグレードする

前回、マスターブランチまで間違って上げてしまっていたので、Kubernetes Version が上がる `v2.15.0` へスキップして上げる

実施順番としては kubespray tag の順番で、 →`v2.15.0`→`v2.15.1`→`v2.16.0`→`v2.17.0`→`v2.17.1`となる

#### kubespray の現バージョンの確認とアップグレード

最新の kubespray を `git pull` する

```
% git describe --tags
v2.14.0-133-g0f7341bd
% git pull
~省略~
% % git describe --tags  
v2.17.0-105-gb5a5478a
```

#### v1.19.3 -> v1.19.7 -> v1.19.9 (kubespray: v2.14.0-133-g0f7341bd -> v2.15.0 -> v2.15.1)

```
git checkout v2.15.0
```

```
% git describe --tags 
v2.15.0
```

```
% pip3 install -r requirements.txt --user

Collecting ansible==2.9.16 (from -r requirements.txt (line 1))
~省略~
Successfully installed ansible-2.9.16
```

```sh:parameter_update
cp -rp inventory/mycluster inventory/mycluster_bak
rm -Rf inventory/mycluster/   
cp -rfp inventory/sample inventory/mycluster    
cp -p inventory/mycluster_bak/hosts.yaml inventory/mycluster/hosts.yaml
```

※前回間違って master まで上げてしまっているので、[安全ではない方法](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/upgrades.md#unsafe-upgrade-example)で上げる

```sh:unsafe_upgrade
ansible-playbook cluster.yml -i inventory/mycluster/hosts.yaml -e kube_version=v1.19.7 -e upgrade_cluster_setup=true -vvv --user root
```

##### エラー対応

下記表示となりエラー終了 (何回か繰り返しても同じ)

```
Failed to execute command: error parsing document: cannot parse string '{\"apiVersion\": \"projectcalico.org/v3\", \"kind\": \"BGPPeer\", \"metadata\": {",
```

[#7216](https://github.com/kubernetes-sigs/kubespray/issues/7216
) の issue のようだったので、[v2.15.1](https://github.com/kubernetes-sigs/kubespray/releases/tag/v2.15.1) で、#7224 として Merge されている
v2.15.1 で再実施する

```
git checkout v2.15.1
```

```
% git describe --tags 
v2.15.1
```

```
% pip3 install -r requirements.txt --user
```

```sh:parameter_update
cp -rp inventory/mycluster inventory/mycluster_bak_2.15.0
rm -Rf inventory/mycluster/
cp -rfp inventory/sample inventory/mycluster    
cp -p inventory/mycluster_bak_2.15.0/hosts.yaml inventory/mycluster/hosts.yaml
```

```sh:unsafe_upgrade
ansible-playbook cluster.yml -i inventory/mycluster/hosts.yaml -e kube_version=v1.19.9 -e upgrade_cluster_setup=true -vvv --user root
```

下記の通り failed=0 で完了

```
PLAY RECAP ********************************************************************************************************************************************************
k8scalicorr01              : ok=342  changed=26   unreachable=0    failed=0    skipped=588  rescued=0    ignored=0   
k8scalicorr02              : ok=342  changed=26   unreachable=0    failed=0    skipped=582  rescued=0    ignored=0   
k8smaster01                : ok=526  changed=57   unreachable=0    failed=0    skipped=1065 rescued=0    ignored=0   
k8smaster02                : ok=454  changed=48   unreachable=0    failed=0    skipped=932  rescued=0    ignored=0   
k8smaster03                : ok=456  changed=49   unreachable=0    failed=0    skipped=930  rescued=0    ignored=0   
k8sworker01                : ok=331  changed=24   unreachable=0    failed=0    skipped=572  rescued=0    ignored=0   
k8sworker02                : ok=331  changed=24   unreachable=0    failed=0    skipped=571  rescued=0    ignored=0   
k8sworker03                : ok=331  changed=24   unreachable=0    failed=0    skipped=571  rescued=0    ignored=0   
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
```

次からは通常のアップグレード手順で実施していく

#### v1.19.9 -> v1.20.7 (kubespray: v2.15.1 -> v2.16.0)

```
git checkout v2.16.0
```

```
% git describe --tags 
v2.16.0
```

```
% pip3 install -r requirements.txt --user
```

```sh:parameter_update
cp -rp inventory/mycluster inventory/mycluster_bak_2.15.1
rm -Rf inventory/mycluster/
cp -rfp inventory/sample inventory/mycluster    
cp -p inventory/mycluster_bak_2.15.1/hosts.yaml inventory/mycluster/hosts.yaml
```

```sh:cluster-upgrade
ansible-playbook -i inventory/mycluster/hosts.yaml upgrade-cluster.yml -vvv --user root
```

##### エラー対応

実施環境だと、下記のエラー出力となった

```
<192.168.129.25> (1, b'\n{"msg": "Unable to restart service docker: Job for docker.service failed because the control process exited with error code. See \\"systemctl status do
cker.service\\" and \\"journalctl -xe\\" for details.\\n", "failed": true, "invocation": {"module_args": {"no_block": false, "force": null, "name": "docker", "daemon_reexec": false, "en
abled": null, "daemon_reload": false, "state": "restarted", "masked": null, "scope": null, "user": null}}}\n', b'')ESC[0m
<192.168.129.25> Failed to connect to the host via ssh: 
RUNNING HANDLER [container-engine/docker : Docker | reload docker]
~中略~
    "msg": "Unable to restart service docker: Job for docker.service failed because the control process exited with error code. See \"systemctl status docker.service\" and \"jo
urnalctl -xe\" for details.\n
```

下記を 該当ノードへログイン(root)して実施

```
rm -rf /var/run/docker.sock
systemctl restart docker
```

再度実施

```sh:cluster-upgrade
ansible-playbook -i inventory/mycluster/hosts.yaml upgrade-cluster.yml -vvv --user root
```

下記の通り failed=0 で完了

```
PLAY RECAP ********************************************************************************************************************************************************
k8scalicorr01              : ok=375  changed=26   unreachable=0    failed=0    skipped=697  rescued=0    ignored=0   
k8scalicorr02              : ok=375  changed=26   unreachable=0    failed=0    skipped=691  rescued=0    ignored=0   
k8smaster01                : ok=542  changed=32   unreachable=0    failed=0    skipped=1333 rescued=0    ignored=0   
k8smaster02                : ok=484  changed=36   unreachable=0    failed=0    skipped=1070 rescued=0    ignored=0   
k8smaster03                : ok=486  changed=37   unreachable=0    failed=0    skipped=1068 rescued=0    ignored=0   
k8sworker01                : ok=363  changed=23   unreachable=0    failed=0    skipped=677  rescued=0    ignored=0   
k8sworker02                : ok=363  changed=23   unreachable=0    failed=0    skipped=676  rescued=0    ignored=0   
k8sworker03                : ok=363  changed=23   unreachable=0    failed=0    skipped=676  rescued=0    ignored=0   
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
```

```
% kubectl get node            
NAME            STATUS   ROLES                  AGE    VERSION
k8scalicorr01   Ready    <none>                 696d   v1.20.7
k8scalicorr02   Ready    <none>                 696d   v1.20.7
k8smaster01     Ready    control-plane,master   698d   v1.20.7
k8smaster02     Ready    control-plane,master   698d   v1.20.7
k8smaster03     Ready    control-plane,master   698d   v1.20.7
k8sworker01     Ready    <none>                 698d   v1.20.7
k8sworker02     Ready    <none>                 698d   v1.20.7
k8sworker03     Ready    <none>                 698d   v1.20.7
```


#### v1.20.7 -> v1.21.5 (v2.16.0 -> v2.17.0)

```
git checkout v2.17.0
```

```
% git describe --tags 
v2.17.0
```

```
% pip3 install -r requirements.txt --user
```

※実行環境だと ansible install でエラーが出たため、 `pip uninstall ansible`を実施して上記コマンド再実施をした 

```sh:parameter_update
cp -rp inventory/mycluster inventory/mycluster_bak_2.16.0
rm -Rf inventory/mycluster/
cp -rfp inventory/sample inventory/mycluster
cp -p inventory/mycluster_bak_2.16.0/hosts.yaml inventory/mycluster/hosts.yaml
```


```sh:cluster-upgrade
ansible-playbook -i inventory/mycluster/hosts.yaml upgrade-cluster.yml -vvv --user root
```

前回同様のエラーが出たため、下記を 該当ノードへログインして実施

```
rm -rf /var/run/docker.sock
systemctl restart docker
```

master ノード1系が cordon になっていたので、uncordon しておく

```
% kubectl get node
NAME            STATUS                     ROLES                  AGE    VERSION
k8scalicorr01   Ready                      <none>                 696d   v1.20.7
k8scalicorr02   Ready                      <none>                 696d   v1.20.7
k8smaster01     Ready,SchedulingDisabled   control-plane,master   698d   v1.20.7
k8smaster02     Ready                      control-plane,master   698d   v1.20.7
k8smaster03     Ready                      control-plane,master   698d   v1.20.7
k8sworker01     Ready                      <none>                 698d   v1.20.7
k8sworker02     Ready                      <none>                 698d   v1.20.7
k8sworker03     Ready                      <none>                 698d   v1.20.7
% kubectl uncordon k8smaster01
node/k8smaster01 uncordoned
% kubectl get node                  
NAME            STATUS   ROLES                  AGE    VERSION
k8scalicorr01   Ready    <none>                 696d   v1.20.7
k8scalicorr02   Ready    <none>                 696d   v1.20.7
k8smaster01     Ready    control-plane,master   698d   v1.20.7
k8smaster02     Ready    control-plane,master   698d   v1.20.7
k8smaster03     Ready    control-plane,master   698d   v1.20.7
k8sworker01     Ready    <none>                 698d   v1.20.7
k8sworker02     Ready    <none>                 698d   v1.20.7
k8sworker03     Ready    <none>                 698d   v1.20.7
```

再度実施

```sh:cluster-upgrade
ansible-playbook -i inventory/mycluster/hosts.yaml upgrade-cluster.yml -vvv --user root
```

```
PLAY RECAP ********************************************************************************************************************************************************
k8scalicorr01              : ok=381  changed=31   unreachable=0    failed=0    skipped=716  rescued=0    ignored=0   
k8scalicorr02              : ok=381  changed=31   unreachable=0    failed=0    skipped=710  rescued=0    ignored=0   
k8smaster01                : ok=555  changed=44   unreachable=0    failed=0    skipped=1352 rescued=0    ignored=0   
k8smaster02                : ok=490  changed=39   unreachable=0    failed=0    skipped=1091 rescued=0    ignored=0   
k8smaster03                : ok=492  changed=41   unreachable=0    failed=0    skipped=1089 rescued=0    ignored=0   
k8sworker01                : ok=369  changed=29   unreachable=0    failed=0    skipped=696  rescued=0    ignored=0   
k8sworker02                : ok=369  changed=29   unreachable=0    failed=0    skipped=695  rescued=0    ignored=0   
k8sworker03                : ok=369  changed=29   unreachable=0    failed=0    skipped=695  rescued=0    ignored=0   
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
```

```
% kubectl get node
NAME            STATUS   ROLES                  AGE    VERSION
k8scalicorr01   Ready    <none>                 696d   v1.21.5
k8scalicorr02   Ready    <none>                 696d   v1.21.5
k8smaster01     Ready    control-plane,master   698d   v1.21.5
k8smaster02     Ready    control-plane,master   698d   v1.21.5
k8smaster03     Ready    control-plane,master   698d   v1.21.5
k8sworker01     Ready    <none>                 698d   v1.21.5
k8sworker02     Ready    <none>                 698d   v1.21.5
k8sworker03     Ready    <none>                 698d   v1.21.5
```


#### v1.21.5 -> v1.21.6 (v2.17.0 -> v2.17.1)

```
git checkout v2.17.1
```

```
% git describe --tags 
v2.17.1
```

```
% pip3 install -r requirements.txt --user
```


```sh:parameter_update
cp -rp inventory/mycluster inventory/mycluster_bak_2.17.0
rm -Rf inventory/mycluster/
cp -rfp inventory/sample inventory/mycluster
cp -p inventory/mycluster_bak_2.17.0/hosts.yaml inventory/mycluster/hosts.yaml
```

```sh:cluster-upgrade
ansible-playbook -i inventory/mycluster/hosts.yaml upgrade-cluster.yml -vvv --user root
```

```
PLAY RECAP ********************************************************************************************************************************************************
k8scalicorr01              : ok=379  changed=25   unreachable=0    failed=0    skipped=711  rescued=0    ignored=0   
k8scalicorr02              : ok=379  changed=25   unreachable=0    failed=0    skipped=705  rescued=0    ignored=0   
k8smaster01                : ok=553  changed=41   unreachable=0    failed=0    skipped=1352 rescued=0    ignored=0   
k8smaster02                : ok=488  changed=38   unreachable=0    failed=0    skipped=1086 rescued=0    ignored=0   
k8smaster03                : ok=490  changed=39   unreachable=0    failed=0    skipped=1084 rescued=0    ignored=0   
k8sworker01                : ok=367  changed=23   unreachable=0    failed=0    skipped=691  rescued=0    ignored=0   
k8sworker02                : ok=367  changed=23   unreachable=0    failed=0    skipped=690  rescued=0    ignored=0   
k8sworker03                : ok=367  changed=23   unreachable=0    failed=0    skipped=690  rescued=0    ignored=0   
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Saturday 13 November 2021  16:10:42 +0900 (0:00:00.143)       0:22:36.897 ***** 

```

```
% kubectl get node
NAME            STATUS   ROLES                  AGE    VERSION
k8scalicorr01   Ready    <none>                 696d   v1.21.6
k8scalicorr02   Ready    <none>                 696d   v1.21.6
k8smaster01     Ready    control-plane,master   698d   v1.21.6
k8smaster02     Ready    control-plane,master   698d   v1.21.6
k8smaster03     Ready    control-plane,master   698d   v1.21.6
k8sworker01     Ready    <none>                 698d   v1.21.6
k8sworker02     Ready    <none>                 698d   v1.21.6
k8sworker03     Ready    <none>                 698d   v1.21.6
```

上記の通り、予定していた `v1.21.6` までのクラスタアップグレードを完了

## おわりに
kubespray で kubernetes クラスタのアップグレード作業を実施した
hosts.yaml への表記変更でつまったり、Timeoutで何度か失敗したりしたが、完了することができた
今後も定期的なアップグレードをしていきたい

## 参照
GitHub kubernetes-sigs/kubespray
https://github.com/kubernetes-sigs/kubespray
Upgrading Kubernetes in Kubespray
https://github.com/kubernetes-sigs/kubespray/blob/master/docs/upgrades.md
Understanding Docker Hub Rate Limiting
https://www.docker.com/increase-rate-limits