LoginSignup
0
0

More than 1 year has passed since last update.

Lima で k3s 環境を構築し BuildKit でアプリをビルドして実行

Posted at

Limak3s を使った Kubernetes 環境を構築し、サンプルアプリケーションをビルドして実行します。

1. k3s の環境構築

まずは、https://github.com/lima-vm/lima/blob/master/examples/k3s.yaml を参考に、k3s を実行するための Lima の構成ファイルを次のようにしてみました。

コンテナは k3s が管理するので containerd の設定を false にして、あとは k3s をインストールするだけで良さそうです。

なお、~/temp/lima_k3s で作業を行うように書き込み可でマウントしています。

lima_k3s.yaml
images:
...省略

mounts:
- location: "~/temp/lima_k3s"
  writable: true

containerd:
  system: false
  user: false

provision:
- mode: system
  script: |
    #!/bin/sh
    curl -sfL https://get.k3s.io | sh -

probes:
- script: |
    #!/bin/bash
    set -eux -o pipefail
    if ! timeout 30s bash -c "until test -f /etc/rancher/k3s/k3s.yaml; do sleep 3; done"; then
            echo >&2 "k3s is not running yet"
            exit 1
    fi

このファイルで Lima を実行し、シェルへ入っておきます。

実行例
% cd ~/temp/lima_k3s
% limactl start --tty=false lima_k3s.yaml
・・・

% limactl shell lima_k3s
$ 

以降の作業は基本的に lima_k3s シェルで実施します。

2. コンテナイメージのビルド

上記で構築した環境では nerdctl がインストールされないので、コンテナイメージをビルドする手段が無さそうです。

そこで、ここでは BuildKit でコンテナイメージをビルドします。

2-1. BuildKit インストール

今回は BuildKit をダウンロードして手動でインストールしました。
解凍すると ./bin が作られるので、その中のコマンド群を /usr/local/bin へ配置しています。

BuildKit インストール例
$ wget https://github.com/moby/buildkit/releases/download/v0.11.6/buildkit-v0.11.6.linux-arm64.tar.gz
$ tar zxf buildkit-v0.11.6.linux-arm64.tar.gz
$ sudo cp ./bin/* /usr/local/bin/
$ rm -fr ./bin

2-2. サンプルアプリケーション

次のような Rust アプリケーションをビルドする事にします。

ファイル一式は ~/temp/lima_k3s/sampleapp へ配置しているものとします。

Cargo.toml
[package]
name = "sampleapp"
version = "0.1.0"
edition = "2021"

[dependencies]
gotham = "0.7"

[profile.release]
lto = true
src/main.rs
use gotham::state::State;
use gotham::prelude::FromState;
use gotham::hyper::Uri;

use std::env;

fn sample(state: State) -> (State, String) {
    let uri = Uri::borrow_from(&state);
    println!("path={}", uri);

    let res = format!("ok:{}", uri);

    (state, res)
}

fn main() {
    let port = env::var("APP_PORT").unwrap_or("3000".to_owned());
    let addr = format!("0.0.0.0:{}", port);

    println!("listening: {}", addr);

    gotham::start(addr, || Ok(sample)).unwrap();
}
Dockerfile
FROM rust:1.69 as builder

WORKDIR /app

COPY . .

RUN cargo install --path .

FROM debian:bullseye-slim

WORKDIR /app

RUN apt-get update && rm -rf /var/lib/apt/lists/*

COPY --from=builder /usr/local/cargo/bin/sampleapp .

CMD ["./sampleapp"]

Dockerfile は https://hub.docker.com/_/rust の内容を参考にしましたが、これだと cargo install 実行時に依存パッケージの処理が毎回行われるので、あまり効率的では無さそうでした。

2-3. ビルド

buildkitd を実行しておき、buildctl を使ってコンテナイメージをビルドします。

今回は k3s へコンテナイメージを直接インポートする事にしたので、コンテナイメージを tar ファイル(sampleapp.tar)へ出力しています。

buildkitd 実行例
$ sudo buildkitd &
ビルド例
$ sudo buildctl build --frontend dockerfile.v0 \
  --local context=./sampleapp --local dockerfile=./sampleapp \
  --output type=oci,name=sampleapp > sampleapp.tar
buildkitd 終了例
$ sudo killall buildkitd

3. 実行

まずは、sampleapp.tar を k3s ctr でインポートしておきます。

コンテナイメージのインポート
$ sudo k3s ctr images import sampleapp.tar

実行用の Deployment + Service の構成ファイルを用意します。

インポートしたコンテナイメージを使うので imagePullPolicy: Never としています。

sampleapp.yaml
kind: Service
apiVersion: v1
metadata:
  name: sampleapp
  labels:
    app: sampleapp
spec:
  selector:
    app: sampleapp
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 3000
  type: LoadBalancer

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sampleapp
  labels:
    app: sampleapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sampleapp
  template:
    metadata:
      labels:
        app: sampleapp
    spec:
      containers:
      - name: sampleapp
        image: sampleapp
        ports:
        - containerPort: 3000
        imagePullPolicy: Never

kubectl apply を実行してリソースを作成します。

リソース作成
$ sudo kubectl apply -f sampleapp.yaml

service/sampleapp created
deployment.apps/sampleapp created

次のようになりました。

Pod 確認
$ sudo kubectl get pods

NAME                         READY   STATUS    RESTARTS   AGE
sampleapp-6786f87bd7-gs6sq   1/1     Running   0          6s
Service 確認
$ sudo kubectl get svc

NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)          AGE
kubernetes   ClusterIP      10.43.0.1      <none>         443/TCP          122m
sampleapp    LoadBalancer   10.43.198.42   192.168.5.15   8080:30201/TCP   10s

最後にホスト OS(macOS)からアクセスしてみます。

動作確認1
% curl http://localhost:8080/   
ok:/
動作確認2
% curl http://localhost:8080/ab
ok:/ab
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0