Raspberry Pi 4B上のMinikubeでConcourse CIを動かす

# 1. インストールコマンド
```shell_session
$ kubectl create namespace concourse
$ helm repo add concourse https://concourse-charts.storage.googleapis.com/
$ helm install -n concourse concourse concourse/concourse --set image='rdclda/concourse' --set imageTag='7.9.1' --set concourse.worker.runtime='containerd'
～略～
    export POD_NAME=$(kubectl get pods --namespace concourse -l "app=concourse-web" -o jsonpath="{.items[0].metadata.name}")
    echo "Visit http://127.0.0.1:8080 to use Concourse"
    kubectl port-forward --namespace concourse $POD_NAME 8080:8080
～略～
$ export POD_NAME=$(kubectl get pods --namespace concourse -l "app=concourse-web" -o jsonpath="{.items[0].metadata.name}")
$ kubectl port-forward --namespace concourse $POD_NAME 8080:808
```

公式の手順：https://github.com/concourse/concourse-chart

# 2. 前提情報
## 2.1. ハードウェア
Raspberry Pi 4Bを使用、USB SSDでboot、オーバークロック（1.8GHz->2.1GHz）済み

```shell_session
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 11 (bullseye)
Release:	11
Codename:	bullseye
$ uname -a
Linux rpi-4b-1 6.6.16-v8+ #1728 SMP PREEMPT Tue Feb  6 17:21:42 GMT 2024 aarch64 GNU/Linux
$ lscpu
Architecture:                       aarch64
CPU op-mode(s):                     32-bit, 64-bit
Byte Order:                         Little Endian
CPU(s):                             4
On-line CPU(s) list:                0-3
Thread(s) per core:                 1
Core(s) per socket:                 4
Socket(s):                          1
Vendor ID:                          ARM
Model:                              3
Model name:                         Cortex-A72
Stepping:                           r0p3
CPU max MHz:                        2100.0000
CPU min MHz:                        1800.0000
BogoMIPS:                           108.00
L1d cache:                          128 KiB
L1i cache:                          192 KiB
L2 cache:                           1 MiB
Vulnerability Gather data sampling: Not affected
Vulnerability Itlb multihit:        Not affected
Vulnerability L1tf:                 Not affected
Vulnerability Mds:                  Not affected
Vulnerability Meltdown:             Not affected
Vulnerability Mmio stale data:      Not affected
Vulnerability Retbleed:             Not affected
Vulnerability Spec rstack overflow: Not affected
Vulnerability Spec store bypass:    Vulnerable
Vulnerability Spectre v1:           Mitigation; __user pointer sanitization
Vulnerability Spectre v2:           Vulnerable
Vulnerability Srbds:                Not affected
Vulnerability Tsx async abort:      Not affected
Flags:                              fp asimd evtstrm crc32 cpuid
$ sudo lshw -short -C memory
H/W path            Device           Class      Description
===========================================================
/0/1/0                               memory     32KiB L1 Cache
/0/2/0                               memory     32KiB L1 Cache
/0/3/0                               memory     32KiB L1 Cache
/0/4/0                               memory     32KiB L1 Cache
/0/6                                 memory     7808MiB System memory
```

## 2.2. Minikube
* minikube v1.31.0
* Docker 24.0.4
* Kubernetes v1.27.3

```shell_session
$ minikube start
😄  Raspbian 11.9 (arm64) 上の minikube v1.32.0
🆕  Kubernetes 1.28.3 が利用可能です。アップグレードしたい場合、--kubernetes-version=v1.28.3 を指定してください
✨  既存のプロファイルを元に、docker ドライバーを使用します
👍  minikube クラスター中のコントロールプレーンの minikube ノードを起動しています
🚜  ベースイメージを取得しています...
🔄  「minikube」のために既存の docker container を再起動しています...
❗  イメージが現在の minikube バージョンでビルドされていません。minikube クラスターを削除後、最新のイメージを使用してクラスターを再作成することでこの問題を解決することができます。想定された minikube のバージョン:  v1.31.0 -> 実際の minikube のバージョン: v1.32.0
🐳  Docker 24.0.4 で Kubernetes v1.27.3 を準備しています...
🔗  bridge CNI (コンテナーネットワークインターフェース) を設定中です...
🔎  Kubernetes コンポーネントを検証しています...
    ▪ registry.k8s.io/ingress-nginx/controller:v1.9.4 イメージを使用しています
    ▪ registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20231011-8b53cabe0 イメージを使用しています
    ▪ registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20231011-8b53cabe0 イメージを使用しています
    ▪ registry.k8s.io/metrics-server/metrics-server:v0.6.4 イメージを使用しています
    ▪ docker.io/kubernetesui/dashboard:v2.7.0 イメージを使用しています
    ▪ docker.io/kubernetesui/metrics-scraper:v1.0.8 イメージを使用しています
    ▪ gcr.io/k8s-minikube/storage-provisioner:v5 イメージを使用しています
    ▪ gcr.io/k8s-minikube/minikube-ingress-dns:0.0.2 イメージを使用しています
🔎  ingress アドオンを検証しています...
💡  いくつかのダッシュボード機能は metrics-server アドオンを必要とします。全機能を有効にするためには、次のコマンドを実行します:

	minikube addons enable metrics-server	


🌟  有効なアドオン: storage-provisioner, ingress-dns, metrics-server, default-storageclass, dashboard, ingress
🏄  終了しました！kubectl がデフォルトで「minikube」クラスターと「default」ネームスペースを使用するよう設定されました
```

## 2.3. Minikube addons
```shell_session
$ minikube addons list
|-----------------------------|----------|--------------|--------------------------------|
|         ADDON NAME          | PROFILE  |    STATUS    |           MAINTAINER           |
|-----------------------------|----------|--------------|--------------------------------|
| ambassador                  | minikube | disabled     | 3rd party (Ambassador)         |
| auto-pause                  | minikube | disabled     | minikube                       |
| cloud-spanner               | minikube | disabled     | Google                         |
| csi-hostpath-driver         | minikube | disabled     | Kubernetes                     |
| dashboard                   | minikube | enabled ✅   | Kubernetes                     |
| default-storageclass        | minikube | enabled ✅   | Kubernetes                     |
| efk                         | minikube | disabled     | 3rd party (Elastic)            |
| freshpod                    | minikube | disabled     | Google                         |
| gcp-auth                    | minikube | disabled     | Google                         |
| gvisor                      | minikube | disabled     | minikube                       |
| headlamp                    | minikube | disabled     | 3rd party (kinvolk.io)         |
| helm-tiller                 | minikube | disabled     | 3rd party (Helm)               |
| inaccel                     | minikube | disabled     | 3rd party (InAccel             |
|                             |          |              | [info@inaccel.com])            |
| ingress                     | minikube | enabled ✅   | Kubernetes                     |
| ingress-dns                 | minikube | enabled ✅   | minikube                       |
| inspektor-gadget            | minikube | disabled     | 3rd party                      |
|                             |          |              | (inspektor-gadget.io)          |
| istio                       | minikube | disabled     | 3rd party (Istio)              |
| istio-provisioner           | minikube | disabled     | 3rd party (Istio)              |
| kong                        | minikube | disabled     | 3rd party (Kong HQ)            |
| kubeflow                    | minikube | disabled     | 3rd party                      |
| kubevirt                    | minikube | disabled     | 3rd party (KubeVirt)           |
| logviewer                   | minikube | disabled     | 3rd party (unknown)            |
| metallb                     | minikube | disabled     | 3rd party (MetalLB)            |
| metrics-server              | minikube | enabled ✅   | Kubernetes                     |
| nvidia-device-plugin        | minikube | disabled     | 3rd party (NVIDIA)             |
| nvidia-driver-installer     | minikube | disabled     | 3rd party (Nvidia)             |
| nvidia-gpu-device-plugin    | minikube | disabled     | 3rd party (Nvidia)             |
| olm                         | minikube | disabled     | 3rd party (Operator Framework) |
| pod-security-policy         | minikube | disabled     | 3rd party (unknown)            |
| portainer                   | minikube | disabled     | 3rd party (Portainer.io)       |
| registry                    | minikube | disabled     | minikube                       |
| registry-aliases            | minikube | disabled     | 3rd party (unknown)            |
| registry-creds              | minikube | disabled     | 3rd party (UPMC Enterprises)   |
| storage-provisioner         | minikube | enabled ✅   | minikube                       |
| storage-provisioner-gluster | minikube | disabled     | 3rd party (Gluster)            |
| storage-provisioner-rancher | minikube | disabled     | 3rd party (Rancher)            |
| volumesnapshots             | minikube | disabled     | Kubernetes                     |
|-----------------------------|----------|--------------|--------------------------------|
```

# 3. 解説
Concourse CIを動かすには公式から提供されているコンテナとHelm Chartを使えば簡単にk8s(minikube)上で起動できるはずだが、動かなかった。Concourse CIを動かすためには、PostgreSQLのほかにwebとworker-0、worker-1が起動しなければならないが、いずれのworkerも起動しなかった。ログとしては以下の通り。
```shell_session
Defaulted container "concourse-worker" out of: concourse-worker, concourse-worker-init-rm (init)
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
```

すっかり失念していたが、ラズパイはプロセッサがARM(AArch64)でありx86(x64)系やAMD64系とは互換性がない。workerのコンテナ内にあるバイナリがamd64でビルドされていたようで、それが原因で上記エラーが発生していたものと思われる。

いろいろ探した結果、以下を見つけた。
https://github.com/robinhuiser/concourse-arm64

arm64で動くようビルドされたコンテナが公開されているようだったので、`helm install`時に` --set image='rdclda/concourse' --set imageTag='7.9.1'`を渡すようにした。また、デフォルトのランタイムだと`guardian`※というのを使っているらしく、それでは動作しなかったため` --set concourse.worker.runtime='containerd'`を追加している。最終的には本ページの最初に記載したコマンドとなった。

※よくわかっていないがConcourseが提供しているコンテナランタイムらしい、以下に記載がある。
　https://concourse-ci.org/concourse-worker.html#guardian-runtime