Rancher2サーバが落ちていて起動しない時の対処(2021年皐月)

# 初めに
こんにちは、今更な感じもありますが、困っている人がいるかもしれないのと、自分の備忘録を兼ねて本書を記します。ご覧になっていただき、読者のみなさまに感謝します。

**壬寅(2022)年卯月二十日更新：** 時々参考にしてくれている人がいることと、今年も同じ目にあってしまったため、ちょっとだけスクリプトを更新した。なお、マイナーバージョンの初期版(v2.x.0)に更新しただけでは問題が解決せず、最新パッチ版に上げることで解決できた。
(v2.4.13で1年以上放置->v2.4.18->v2.5.0->v2.5.13で解決)

:::note info
なお、2.6系への更新はやめておいた方がよい。試しにやっていみたが以下のような問題が発生して2.5系に戻した。
- 「cert-manager」などの更新が必要
- SingleNode構成ではK3Sサーバの初期化で無限ループとなる問題がある
- 既存のIngressにも問題が発生してしまい、使い物にならない
:::

## 対象の読者
以下のような方々のお役にたてれば幸いです。

- rancher2を内部自己署名TLS証明書で動かしている
- 導入してから1年以上アップデートしていない
- 久しぶりに管理画面を見ようとしたらサーバが停止していた
- 更新方法がよくわからない

## 原因
Rancher内臓のTLS証明書の期限が1年間であり、放置していると切れてしまい、証明書不正で動作不可となった。これは再起動しても改善されない。

## 課題
既存Rancher環境での緒設定を壊してしまうと、最初からさ設定のやり直しになるので、正規の手順に従って作業する必要がある。

# 対処方法
Rancher2サーバのデータ領域からTSL証明書を削除し、新バージョンにアップデートすれば、TLS証明書も新規作成されて動作するようになる、さらにどのバージョンからかは忘れたが、再起動か何かで古いTLS証明書を再作成する機能が加わったようだ。

## Rancher2 update tls
以下の記事を参考にして、順次アップデートしていく。

https://rancher.com/docs/rancher/v2.x/en/installation/other-installation-methods/single-node-docker/single-node-upgrades/


以下のようにして、処理をすすめる。

### １．サーバの確認
rancher2サーバのバージョンを確認。

```bash
docker ps -a
```

#### 出力の一例
rancher2サーバのIMAGE(イメージ名)は、「rancher/rancher:TAG」となっていて、大抵は最後の行に現れる。下の例では「rancher/ranchre:stable」となっており、NAMES(名称)は「rancher2-server」となっている。なお、名称は起動時の指定で好きにつけられるので、別の名前になっていることもある。

```
CONTAINER ID        IMAGE                                                                                                      COMMAND                  CREATED             STATUS                        PORTS               NAMES
f4b50bdeed46        f29ece87a195                                                                                               "run.sh"                 13 seconds ago      Exited (1) 13 seconds ago                         k8s_cluster-register_cattle-cluster-agent-db695c944-nwrlp_cattle-system_bab5ca79-ad23-4644-9373-c818ba29e69d_1739
. . . . .
7063f22dd646        rancher/rancher-agent:v2.3.5                                                                               "run.sh -- share-r..."   14 months ago       Exited (0) 6 days ago                             share-mnt
9e2eee18a879        rancher/rancher:stable                                                                                     "entrypoint.sh"          14 months ago       Restarting (1) 30 hours ago                       rancher2-server
```

#### バージョン確認
TAGがstableだと、実際のバージョンが不明なので、「docker inspect」 にて調査する。

```bash
docker inspect 9e2eee18a879 | grep "CATTLE_SERVER_VERSION"
# 出力例
                "CATTLE_SERVER_VERSION=v2.3.5",
```

#### 設定データの保存
「rancher2-server」コンテナを停止し、データを保存するコンテナ「rancher2-data」を作成する。

```bash
# stop rancher2-server
docker stop  rancher2-server
# create volume as rancher2-data
docker create --volumes-from rancher2-server --name rancher2-data rancher/rancher:stable
```

#### データ確認
busyboxコンテナを利用し作成したボリューム内のデータを確認する。

```bash
# exec sh with volume
docker run -it --volumes-from rancher2-data -v $PWD:/backup busybox sh
# inspect 上記「busybox」コンテナ内部にて
ls -altr /var/lib/rancher/
# 出力例
total 4
drwxr-xr-x    4 root     root            32 Jan 16  2020 k3s
drwx------    8 root     root           109 Jan 16  2020 management-state
-rw-r--r--    1 root     root             1 Jan 16  2020 .existing
drwxr-xr-x    4 root     root            37 Jan 16  2020 .kube
drwxr-xr-x    5 root     root            71 Jan 16  2020 .
drwxr-xr-x    3 root     root            21 Sep 24 16:21 ..
```

#### バックアップ
busyboxから戻り、バックアップしてからアップデートする。

```bash
# backup
docker run --volumes-from rancher2-data -v $PWD:/backup busybox tar cvzf /backup/rancher-data-backup-ORG.tgz -C /var/lib/ ./rancher
```

<details><summary>busyboxの中でバックアップする場合</summary><div>
すでにバインドマウントはされているので、、、

```bash
# backup in busybox
tar cvzf /backup/rancher-data-backup-ORG-in.tgz -C /var/lib/ ./rancher
```
</div></details>

#### アップデート
方針としては、現バージョンから始め、「最後のパッチバージョン＝＞マイナーバージョンアップ」を繰り返す。rancher独自のTLS証明書を使う場合は、古いTLS証明書を退避してからアップデートする。以下、ポート設定などは標準と異なるので、注意されたし。Rancherの設定やバージョンにより、証明書の置き場所が2か所ありそうなので、両対応するスクリプトとした。

例）v2.3.5=>v2.3.10=>v2.4.0=>v2.4.15=>. . . . .

```bash
# 変数設定
RC2_VER=v2.3.10
TODT=$(date +%y%m%d-%H%M)

# preserve and remove tls
docker run --rm --volumes-from rancher2-data -v $PWD:/backup busybox sh -c "\
  echo bgn preserve && \
  (mkdir -p /var/lib/rancher/bu/k3s_tls || true) && \
  (mv /var/lib/rancher/k3s/server/tls/* /var/lib/rancher/bu/k3s_tls/ || true) && \
  (mkdir -p /var/lib/rancher/bu/management-state_tls || true) && \
  (mv /var/lib/rancher/management-state/tls/* /var/lib/rancher/bu/management-state_tls/ || true) && \
  echo fin preserve \
"

# rename old server
docker rename rancher2-server rancher2-server-old

# get newly image
docker pull rancher/rancher:${RC2_VER}

# start with volume
docker run -d --volumes-from rancher2-data \
  --name=rancher2-server \
  --restart=unless-stopped \
  -p 81:80 -p 444:443 \
  --privileged \
  rancher/rancher:${RC2_VER}
```

#### 動作確認
Rancher2の管理画面にアクセスして状況を確認する。
更新後の初回起動時には通常以上の処理があるとのことで、ある程度待つことが必要とRancher側の説明にあったが、筆者は5分から10分であきらめ、証明書の手動退避や、最新のパッチバージョンへの更新などを試してみた。
複数ノードでクラスタを組んでいる場合など、「cluster unavailable」が表示されて、クラスタ操作不能のトラブルとなる場合もある。

Rancher画面の、cluster -> edit で、
□etcd □controlplane □worker の3つを現状の設定に合わせてチェックして、
クラスタの中心ノードで、表示されたスクリプトを実行してみる。
自分の場合は、これでagentが実行され、環境が正常になった。

```bash
# スクリプトの一例
sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:v2.3.4 --server https://172.30.16.240:444 --token xhwwc2q9475pkz2tqlzzvrfs8mtltdkf2c8gk7gv8ztfhwzwch27n2 --ca-checksum 1aa4680ce04d83a774052634cc6fc23d0d6fe60bb59d5b9e058b40147d4fcdf8 --etcd --controlplane --worker
```

もし、まだ問題があるようなら、docker自体を再起動してみるとよい。起動中のコンテナも再起動になるので、サービス提供中の場合は、メンテの時間を確保してから注意して行うこと。

```bash
sudo systemctl restart docker
```

#### 古いコンテナの削除

```bash
# remove old
docker rm -f rancher2-server-old
```

## アップデートスクリプト
TLSの問題がない場合は、以下のスクリプトをrancher2upとして保存し、次のようにアップデートを自動化できる。(2番目のパラメータは省略可能)
証明書の削除は自動だと不安もあるため、必要に応じて手動実行することとした。
```bash
source rancher2up v2.5.0 20220420-1958JST
```

```bash
# script for bash
# usage: source rancher2up rc2-version date-time
# e.g.)  source rancher2up v2.4.15 20220420-1852JST

# RC2V=v2.3.0
# RC2V=v2.3.11
# RC2V=v2.4.0
# RC2V=v2.4.15
# RC2V=v2.4.18
# RC2V=v2.5.0
# RC2V=v2.5.13

RC2_VER=${1:-$RC2V}
TODT=${2:-$(date +%y%m%d-%H%M)}

# check param
if [[ -z $RC2_VER ]];then
  SCRPT_NM=$(basename ${BASH_SOURCE[0]})
  cat <<[][] >&2
usage: source $SCRPT_NM rc2-version date-time
e.g.)  source $SCRPT_NM v2.4.15 20220420-1852JST
[][]
  return 1
fi

# check version
CRNT_V=`docker ps -a|grep rancher2-server|grep "rancher/rancher:${RC2_VER} "|wc -l`
if [[ $CRNT_V > 0 ]];then
  echo "Same Version" >&2
  return 1
fi

# stop rancher2-server
docker stop  rancher2-server

# Very 1st time: create volume as rancher2-data
# docker create --volumes-from rancher2-server --name rancher2-data rancher/rancher:${RC2_VER}

# # check data container
# docker run --rm -it --volumes-from rancher2-data -v $PWD:/backup busybox sh

# backup
docker run --rm --volumes-from rancher2-data -v $PWD:/backup \
  busybox tar zcvf /backup/rancher-data-backup-bfr_${RC2_VER}-${TODT}.tgz -C /var/lib/ ./rancher

# rename old
docker rename rancher2-server rancher2-server-old
docker rename rancher2-data rancher2-data-old

# get newly image
docker pull rancher/rancher:${RC2_VER}

# create volume as rancher2-data
docker create --volumes-from rancher2-data-old --name rancher2-data rancher/rancher:${RC2_VER}

# remove certs
function removeCerts {
  docker run --rm --volumes-from rancher2-data -v $PWD:/backup busybox sh -c "\
  echo bgn preserve && \
  (mkdir -p /var/lib/rancher/bu/k3s_tls || true) && \
  (mv /var/lib/rancher/k3s/server/tls/* /var/lib/rancher/bu/k3s_tls/ || true) && \
  (mkdir -p /var/lib/rancher/bu/management-state_tls || true) && \
  (mv /var/lib/rancher/management-state/tls/* /var/lib/rancher/bu/management-state_tls/ || true) && \
  echo fin preserve \
"
}

# CALL function
# removeCerts

# start with volume
docker run -d --volumes-from rancher2-data \
  --name=rancher2-server \
  --restart=unless-stopped \
  -p 81:80 -p 444:443 \
  --privileged \
  rancher/rancher:${RC2_VER}

# # check log file
# docker logs rancher2-server > /tmp/rc2.log 2>&1 && less /tmp/rc2.log

# remove old
docker rm -f rancher2-server-old
docker rm -f rancher2-data-old
```

## Docker領域のお掃除
なんやかんやで領域を食いつぶしている場合に、以下のように掃除してみるとよいかも。

### system prune
不要なデータを削除
__注意：rancher2-dataなどのVolumeコンテナは、実行中のコンテナからマウントされていないと消されてしまう__

```bash
docker system prune
```
:::note info
くれぐれも【rancher2-data】を削除しないように！
:::

## builder prune
dockerバージョンが 1.39 以上の場合[^1]

```bash
docker builder prune
```
## log files
ログ削除

```bash
sudo sh -c "ls -al /var/lib/docker/containers/*/*-json.log"
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"
```

参考リンク：

https://qiita.com/zembutsu/items/f577ea8dad6dc64d70b6

[^1]: https://docs.docker.com/engine/reference/commandline/builder_prune/