ラズパイkubernetesにBuildkitインストール

前回構築したラズパイkubernetes をいじってたら早速以下のエラーに遭遇しました。

ubuntu@k8s1:~$ kubectl get pods
NAME                                READY   STATUS             RESTARTS   AGE
postgresql-25fx6                    0/1     CrashLoopBackOff   105        8h
ubuntu@k8s1:~$ kubectl logs postgresql-25fx6
standard_init_linux.go:211: exec user process caused "exec format error"

どうやらCPUアーキテクチャが異なることが原因らしいです。
Raspberry Pi上でイメージをビルドしようと思いましたが、
このラズパイkubernetesはdockerなしで構築したのでdocker buildが使えません。
調べてみるとBuildkitというのが使えそうなのでインストールしてみました。

Buildkitインストール

こちら を参考に進めます。

ubuntu@k8s1:~$ git clone https://github.com/moby/buildkit.git
ubuntu@k8s1:~$ cd buildkit/examples/kubernetes/
ubuntu@k8s1:~/buildkit/examples/kubernetes$ ./create-certs.sh k8s1
Missing mkcert (https://github.com/FiloSottile/mkcert)

mkcert というのが必要みたいです。
ubuntuなので以下のように進めます。

ubuntu@k8s1:~$ sudo apt install libnss3-tools
ubuntu@k8s1:~$ git clone https://github.com/FiloSottile/mkcert && cd mkcert
ubuntu@k8s1:~/mkcert$ go build -ldflags "-X main.Version=$(git describe --tags)"

Command 'go' not found, but can be installed with:

sudo snap install go         # version 1.15.8, or
sudo apt  install golang-go  # version 2:1.13~1ubuntu2
sudo apt  install gccgo-go   # version 2:1.13~1ubuntu2

See 'snap info go' for additional versions.

「requires Go 1.13+」って書いてありましたね。

ubuntu@k8s1:~/mkcert$ sudo apt  install golang-go
ubuntu@k8s1:~/mkcert$ go build -ldflags "-X main.Version=$(git describe --tags)"
go: downloading software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237
go: downloading golang.org/x/net v0.0.0-20201021035429-f5854403a974
go: extracting software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237
go: extracting golang.org/x/net v0.0.0-20201021035429-f5854403a974
go: downloading golang.org/x/text v0.3.3
go: extracting golang.org/x/text v0.3.3
go: finding golang.org/x/net v0.0.0-20201021035429-f5854403a974
go: finding software.sslmate.com/src/go-pkcs12 v0.0.0-20180114231543-2291e8f0f237
go: finding golang.org/x/text v0.3.3

パス通ってなかったので追加。

ubuntu@k8s1:~/mkcert$ export PATH=$PATH:~/mkcert

それでは再チャレンジ!

ubuntu@k8s1:~/buildkit/examples/kubernetes$ ./create-certs.sh k8s1
W0221 12:23:10.550382 1283593 helpers.go:553] --dry-run is deprecated and can be replaced with --dry-run=client.
W0221 12:23:10.721194 1283600 helpers.go:553] --dry-run is deprecated and can be replaced with --dry-run=client.

うまく行ったようなので進めます。

ubuntu@k8s1:~/buildkit/examples/kubernetes$ kubectl apply -f .certs/buildkit-daemon-certs.yaml
secret/buildkit-daemon-certs created
ubuntu@k8s1:~/buildkit/examples/kubernetes$ kubectl apply -f deployment+service.rootless.yaml
deployment.apps/buildkitd created
service/buildkitd created
ubuntu@k8s1:~/buildkit/examples/kubernetes$ kubectl scale --replicas=10 deployment/buildkitd
deployment.apps/buildkitd scaled
ubuntu@k8s1:~/buildkit/examples/kubernetes$ kubectl get pods
NAME                                READY   STATUS             RESTARTS   AGE
buildkitd-cfd4c4794-2v4bh           1/1     Running            0          2m14s
buildkitd-cfd4c4794-7xlt7           1/1     Running            0          2m14s
buildkitd-cfd4c4794-8ltls           1/1     Running            0          2m14s
buildkitd-cfd4c4794-8m9xc           1/1     Running            0          2m14s
buildkitd-cfd4c4794-hx4p5           1/1     Running            0          2m14s
buildkitd-cfd4c4794-jh96b           1/1     Running            0          2m14s
buildkitd-cfd4c4794-kztt8           1/1     Running            0          2m14s
buildkitd-cfd4c4794-nhsdn           1/1     Running            0          2m14s
buildkitd-cfd4c4794-qnwms           1/1     Running            0          2m14s
buildkitd-cfd4c4794-xvg7s           1/1     Running            0          3m33s

うーん。10個もいらなかったですね。
ポートフォワードは外部からアクセスしたかったのでaddressオプションを加えます。

ubuntu@k8s1:~/buildkit/examples/kubernetes$ kubectl port-forward --address 0.0.0.0 service/buildkitd 1234
Forwarding from 0.0.0.0:1234 -> 1234

このコマンドはバックグラウンドで動いてくれないんですね。
気が向いたらロードバランサーを入れてみようと思います。

Buildkit動作テスト

Buildkitを使うにはbuildctlが必要のようです。
普段Mac使っているのでそちらで実行したかったのですが、
うまく動かなかったので今回はWindowsを使いました。
こちら からバイナリをダウンロードしてパスを通してください。
加えて、create-certs.shを実行したディレクトリに「.certs」があると思うので、
それもWindowsにコピーしておいてください。
(以下の例では「C:¥work¥.certs」にコピーしています)

それではビルドにチャレンジします。
冒頭で起動に失敗していたpostgresqlは これ を実行した結果ですので、
sameersbn/postgresql をビルドしてみます。

PS C:¥work> git clone https://github.com/sameersbn/docker-postgresql.git
PS C:¥work> cd .¥docker-postgresql¥
PS C:¥work¥docker-postgresql> 

今回はdocker hubにプッシュすることにしました。
事前にご自身のIDでログインしておいてください。

PS C:¥work¥docker-postgresql> docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: [your Docker ID]
Password:
Login Succeeded

準備ができましたらbuildctlコマンドを実行してください。
長いですねぇ。
output部分などご自身の環境に書き換えてください。

PS C:¥work¥docker-postgresql> buildctl --addr tcp://k8s1:1234 --tlscacert C:¥work¥.certs¥client¥ca.pem --tlscert C:¥work¥.certs¥client¥cert.pem --tlskey C:¥work¥.certs¥client¥key.pem build --frontend dockerfile.v0 --local context=.¥ --local dockerfile=.¥ --output type=image,name=[your Docker ID]]/[your repository name]:docker-postgresql,push=true

うまくいけばDocker Hubにプッシュされていると思います。
arm64になっていますね。

buildkit_k8s_01.png

使ってみます。
postgresql-rc.yml のimageを、プッシュしたイメージに書き換えて実行します。
ちなみにプライベートリポジトリだと認証がうまくいかなかったので、
一旦パブリックリポジトリにして実行しました。

ubuntu@k8s1:~/docker-gitlab/kubernetes$ kubectl delete -f postgresql-rc.yml 
replicationcontroller "postgresql" deleted
ubuntu@k8s1:~/docker-gitlab/kubernetes$ vi postgresql-rc.yml 
ubuntu@k8s1:~/docker-gitlab/kubernetes$ kubectl apply -f postgresql-rc.yml 
replicationcontroller/postgresql created
ubuntu@k8s1:~/docker-gitlab/kubernetes$ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
postgresql-ww9q4                    1/1     Running   0          83s

無事起動できました。

補足

以前 GitLab連携の自己証明書でHTTPS化したレジストリを立てていたので、
そこにプッシュしようとしたのですが、うまくいかなかったです。
うーん。気が向いたら調べてみようと思います。

PS C:¥work¥docker-postgresql> buildctl --addr tcp://k8s1:1234 --tlscacert C:¥work¥.certs¥client¥ca.pem --tlscert C:¥work¥.certs¥client¥cert.pem --tlskey C:¥work¥.certs¥client¥key.pem build --frontend dockerfile.v0 --local context=.¥ --local dockerfile=.¥ --output type=image,name=example.tsuchinokometal.com/root/my-registry/docker-postgresql:12-20200524,push=true
[+] Building 3.8s (14/14) FINISHED

------
 > exporting to image:
------
error: failed to solve: rpc error: code = Unknown desc = failed to do request: Head https://example.tsuchinokometal.com/v2/root/my-registry/docker-postgresql/blobs/sha256:20029748fc3262f126f61c601993ab4198b5dc8c5326f84597090831540b9c91: x509: certificate signed by unknown authority

PS C:¥work¥docker-postgresql> buildctl --addr tcp://k8s1:1234 --tlscacert C:¥work¥.certs¥client¥ca.pem --tlscert C:¥work¥.certs¥client¥cert.pem --tlskey C:¥work¥.certs¥client¥key.pem build --frontend dockerfile.v0 --local context=.¥ --local dockerfile=.¥ --output type=image,name=example.tsuchinokometal.com:5000/root/my-registry/docker-postgresql:12-20200524,push=true,registry.insecure=true
[+] Building 3.0s (14/14) FINISHED

------
 > exporting to image:
------
error: failed to solve: rpc error: code = Unknown desc = failed to fetch anonymous token: unexpected status: 403 Forbidden