LoginSignup
5
3

Skaffold + MicroK8s で快適なコンテナ開発環境を構築する(WSL/Ubuntu編)

Last updated at Posted at 2022-09-15

クラウドエンジニアの @aoyagi9936 です。
Mac での構築方法は同時に公開した記事を参照してください。

開発環境の構築はエンジニアにとって最初の登竜門ですが、コンテナ環境は特に Docker Desktop の有料化やローカルでの Kubernetes の実行などのハードルもあり、経験豊富なエンジニアにとっても一筋縄にはいかない難しさがあるように感じます。

今回は Windows(WSL) Mac Linux(Ubuntu) ユーザーが同一の開発体験を得られることを目標にコンテナ開発環境の構築方法をご紹介します。
また、

  • Kubernetes を学びたいがどうして良いかわからない
  • 本番環境に近いコンテナ実行環境 をローカルで実現したい
  • CI/CD を回して高速にコンテナアプリケーションを開発したい

という方も参考にしてみてください。

Skaffold とは

Google が開発しオープンソースで提供している、ローカルで Kubernetes ネイティブなアプリケーションを開発するためのコマンドラインツールです。
Golang で書かれておりシングルバイナリで動きます。
Google Cloud Deploy を用いればローカルだけではなくクラウドでもデリバリーパイプラインを構築できますし、Kustomize Helm など Kubernetes をより効率的に扱う支援ツールにも対応しているので覚えておいて損はないと思います。

MicroK8s とは

MicroK8s はローカルでも動作する軽量な Kubernetes ディストリビューションです。
他の候補としては MinikubeK3s 等が挙げられますが、 MicroK8s はエンタープライズサポートや複数ノード対応など本番環境としての運用も可能で、開発や本番で有用なアドオンも充実しているのが特徴です。
詳しくは本家の比較表を参照してください。

MicroK8s vs K3s vs minikube

ちなみに私は以前は Minikube を使っていましたが registry hostpath-storage linkerd といった実用的なアドオンに惹かれて乗り換えました。

Windows (WSL) の準備

※ Ubuntu の方は Ubuntu に MicroK8s をインストールする まで飛ばしてください。

WSL2 のセットアップ

Windows のバージョンによってセットアップ方法は微妙に異なるため詳細は割愛しますが、以下の手順で WSL が使えるようになります。
WSL には現在 WSL1WSL2 がありますが、より忠実に Linux 環境を再現できる WSL2 を利用します。1

  1. コントロールパネルから Windowsの機能の有効化または無効化 を表示
  2. Linux用Windowsサブシステム 仮想マシンプラットフォーム にチェック
  3. Windows を再起動
  4. コマンドプロンプトを開き wsl --set-default-version 2 を実行

WSL2 requires an update to its kernel component. For information please visit https://aka.ms/wsl2kernel というエラーが表示される場合は指示に従ってリンク先のページから x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ (wsl_update_x64.msi) をインストールしてください。

WSL2 で Ubuntu (18.04 or 20.04 or 22.04) を利用する

  1. コマンドプロンプトを開き wsl --install -d Ubuntu-[18.04|20.04|22.04] を実行
  2. wsl -l -v を実行し VERSION2 になっていることを確認
  3. 任意のID/PASSでログインし sudo apt update sudo apt -y upgrade を実行

WSL での MicroK8s 文字化け対策

Cascadia Code をインストールします。
ページ内の Github リリースページ リンク から zip をダウンロードして展開し、 .ttf をダブルクリックして Windows にフォントをインストールします。
WSL ウィンドウを右クリックして Fontタブ > Font のリストボックスに先ほどインストールした Cascadia ... が表示されるので選択して OK を押してください。
ちなみに私は Powerline を愛用しているので Cascadia Mono PL を利用しています。

WSL で systemd を有効にする

2022年9月より WSL が systemd に正式に対応したため面倒なハックが不要となりました。
但し、デフォルトでは有効にはならないため以下の手順で有効化させてください。
まずはコマンドプロンプトか PowerShell で WSL を最新にします。

wsl --update
wsl --set-default-version 2

Ubuntu 上の etc/wsl.confsystemd を有効にします。

echo -e "[boot]\nsystemd=true" | sudo tee /etc/wsl.conf

wsl.conf のその他の設定が知りたい方は Microsoft の公式ドキュメントを参照してください。
有効化できたら WSL を再起動してください。

wsl --shutdown
wsl

以前の記事で紹介したスタートアップスクリプトによる systemd 有効化のハックを使用した方は、スタートアップスクリプトを削除して systemd を有効化してください。

sudo rm /etc/profile.d/00-wsl2-systemd.sh
echo -e "[boot]\nsystemd=true" | sudo tee /etc/wsl.conf

WSL を再起動後にエラーで MicroK8s が起動できない場合は MicroK8s の再インストールが必要ですので以下のコマンドで一旦削除します。

sudo snap remove microk8s

以前の記事も記録として残しておきます。

## WSL で systemd を利用できるようにする

投稿して一週間も経たず内容が陳腐化するとは思ってもいませんでしたが、何と WSL が systemd に正式に対応したそうです。

ですので下記対応は今後は不要となりそうですが未検証ですので記事は残しておきます。

↓↓↓↓↓

Ubuntu に MicroK8s をインストールするためにはパッケージマネージャーの snap を使用しますが、 snap は systemd を利用しており WSL は systemd が利用できない( PID 1 で起動しない)という罠にハマります(ハマりました)。
また、後ほど行うコンテナの Build には Docker Engine を利用するためどちらにせよ WSL で sytemd を利用できるようにしておく必要があります。
最新の WSL2 + Ubuntu22.04 では標準で systemd を PID1 で起動できるようになったようですが、 Ubuntu-18.04 Ubuntu-20.04 では一工夫が必要です。

まずは fontconfigdaemonize をインストールします。

apt install -y fontconfig daemonize

次に /etc/wsl.conf に WSL の設定ファイルを追加します。
<USER_NAME> はご自身で作成したユーザー名を追加してください。

/etc/wsl.conf
[automount]
enabled = true
options = "metadata,uid=1000,gid=1000,umask=22,fmask=11,case=off"
mountFsTab = true
crossDistro = true

[network]
generateHosts = false
generateResolvConf = true

[interop]
enabled = true
appendWindowsPath = true

[user]
default = <USER_NAME>

次に /etc/profile.d/00-wsl2-systemd.sh にスタートアップスクリプトを作成します。

/etc/profile.d/00-wsl2-systemd.sh
SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')

if [ -z "$SYSTEMD_PID" ]; then
   sudo /usr/bin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
   SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')
fi

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
    exec sudo /usr/bin/nsenter -t $SYSTEMD_PID -a su - $LOGNAME
fi

上記は 20.04 の場合ですので 18.04 の場合は daemonize のパスを以下のように変更してください。

- /usr/bin/daemonize
+ /usr/sbin/daemonize

最後に localhost への接続をデフォルトのインターフェースに転送することで MicroK8s に到達できるようにします。

echo 'net.ipv4.conf.all.route_localnet = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf

お疲れ様でした。これで WSL2 で MicroK8s を動かす下準備は終了です。
WSL を再起動したら通常の Ubuntu と同じようにコンテナ開発環境をセットアップしていきます。

Ubuntu に MicroK8s をインストールする

お待たせしました。Ubuntu の方はここから実行してください。
と言っても基本的にインストール方法は公式の通りです。2

メモリが少ないPCの場合は次のコマンドで失敗する可能性があるため念の為余計なプロセスは落としておきましょう(そもそも後続の開発に耐えられない可能性があるのでその環境は非推奨ですが)。

sudo snap install microk8s --classic
# リリースチャンネルを指定する場合
sudo snap install microk8s --classic --channel=1.24

Kubernetes の設定ファイルは .kube に格納します(既存のものと分ける方法は後述)。
存在しない場合は作成し、存在する場合は既存のものとマージします。

cd $HOME
mkdir .kube
cd .kube
microk8s config > config​

作成したフォルダに権限を付与します。

sudo usermod -a -G microk8s $USER
sudo chown -f -R $USER ~/.kube

既存の環境と分けて設定を管理したい場合は先ほどの手順を .kube ではなく .microk8s フォルダで実行し KUBECONFIG 環境変数を利用するか --kubeconfig フラグを利用してください(後述する Skaffold にも --kubeconfig は指定できます)。

export KUBECONFIG=$HOME/.microk8s/config
# または
kubectl --kubeconfig=$HOME/.microk8s/config

再起動し以下のコマンドで Microk8s が正常に動作していることを確認します。
(起動には少し時間がかかります)

microk8s status

MicroK8s には多くの便利なアドオンがありますが今回有効にするのは以下の2つです。

microk8s enable dns
microk8s enable registry

Kubernetes に慣れていない方はダッシュボードを使うことで状態をグラフィカルに確認できます。
アドオンを有効にするだけではなく追加でポートフォワード等の設定も必要なので脚注をご確認ください。3

ダッシュボードのインストールからアクセスに必要な設定までを一度にやってくれるコマンドがあります(version 1.19+)。

microk8s dashboard-proxy

ダッシュボードの起動後にターミナルに URL と トークンが表示されます。
指示の通りに https://127.0.0.1:10443 にアクセスするとトークンを入力できますのでコピー&ペーストしてサインインしてください。

Checking if Dashboard is running.
Infer repository core for addon dashboard
Infer repository core for addon metrics-server
Waiting for Dashboard to come up.
Trying to get token from microk8s-dashboard-token
Waiting for secret token (attempt 0)
Dashboard will be available at https://127.0.0.1:10443
Use the following token to login:
<TOKEN>

image.png

Ubuntu に Docker をインストールする

公式の手順に従ってください。
Install Docker Engine on Ubuntu
今回の趣旨は Skaffold + MicroK8s による Kubernetes ネイティブな開発環境ですので Docker Compose は不要です。

# GPG キーの設定やリポジトリの更新は公式通りのため省略
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin

Ubuntu に Skaffold をインストールする

最後に Skaffold をセットアップします。
快適な環境までもう一息ですので頑張りましょう。

Skaffold のインストールは公式の通りでも良いですし、 Homebrew on Linux でもインストールできます。

Installing Skaffold - skaffold.dev
Homebrew-on-Linux - docs.brew.sh

インストールができたら MicroK8s の組み込みレジストリを登録します。
以下のコマンドで現在の Kubernetes コンテキスト(接続先クラスタ)で利用するレジストリを登録します。

skaffold config set insecure-registries localhost:32000
skaffold config set default-repo localhost:32000

今までの手順の通りであれば Skaffold に登録されるコンテキスト名は microk8s となるはずです。
~/.skaffold/config ファイルの中を見ると設定を確認できますが、異なる場合は kubectl config current-context コマンドを実行して表示されるコンテキスト名を確認してください。

~/.skaffold/config
kubeContexts:
- kube-context: microk8s
  default-repo: localhost:32000
  insecure-registries:
  - localhost:32000

最後に microk8s statusregistry アドオンが enabled であることを確認しておきましょう。
お疲れ様でした。これで環境は完成です!

Skaffold を構成してコンテナをローカルの MicroK8s にデプロイする

Dockerfile と Kubernetes のマニフェストファイルを作成し、 Skaffold で Docker Build と MicroK8s へのデプロイの一連の流れを構成します。
テストシナリオとして Postgres データベースを Pod で立ち上げてローカルから接続してみます。
サンプルソースも用意しておいたので git clone してください。

ディレクトリ構成

.
└── skaffold-microk8s-example/
    ├── skaffold.yaml
    ├── kubernetes-manifests/
    │   └── pod.yaml
    └── src/
        └── infra/
            └── database/
                ├── Dockerfile
                ├── 0_create_database.sql
                └── 1_insert_table.sql

Docker コンテナ設定ファイル

Dockerfile
FROM postgres:14.4-alpine

COPY *.sql /docker-entrypoint-initdb.d/
0_create_database.sql
DROP DATABASE IF EXISTS test_db;
CREATE DATABASE test_db;
1_insert_table.sql
\c test_db;

CREATE TABLE example_tbl (
  id serial PRIMARY KEY,
  name TEXT
);

INSERT INTO example_tbl (name) VALUES ('aoyagi');

Skaffold 設定ファイル

skaffold.yaml
apiVersion: skaffold/v4beta2
kind: Config
build:
  tagPolicy:
    sha256: {}
  local:
    push: true
    useBuildkit: true
  artifacts:
  - image: example-db
    context: src/infra/database
deploy:
  kubeContext: microk8s
profiles:
  - name: local
    portForward:
      - resourceType: pod
        resourceName: my-example-pod
        port: 5432
    manifests:
      rawYaml: [
      "./kubernetes-manifests/pod.yaml"
      ]

Kubernetes マニフェストファイル

pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-example-pod
spec:
  containers:
  - name: my-example-pod
    image: example-db
    ports:
      - containerPort: 5432
    env:
      - name: POSTGRES_USER
        value: postgres
      - name: POSTGRES_PASSWORD
        value: postgres
      - name: POSTGRES_DB
        value: test_db 
      - name: TZ
        value: Asia/Tokyo

全ての準備が整ったら Skaffold を実行してみましょう。
skaffold.yaml のあるパスで以下のコマンドを実行します。

skaffold dev -p local

コンテナが MicroK8s へデプロイされたらお手元のDB接続ツールで接続してみましょう。

接続情報 設定値
ホスト localhost
ポート 5432
ユーザー名 postgres
パスワード postgres
データベース名 test_db

これだけでは Skaffold の良さが伝わりきらないので Skaffoldを実行したまま 1_insert_table.sql にデータを追加してみましょう。

1_insert_table.sql
INSERT INTO example_tbl (name) VALUES ('aoyagi');
+ INSERT INTO example_tbl (name) VALUES ('your_name');

Skaffold が変更を自動で検知してコンテナを再作成し MicroK8s にデプロイします。
開発中は仕様が頻繁に変わりますが変更の都度環境を再作成してくれることで安全性が高まります。
環境をイミュータブルに作成することの良さはまたどこかでお伝えできればと思いますが、タイトルの目標は達成できましたので本記事はここまでとなります。

本投稿が皆様の快適なコンテナ開発ライフの一助になれば幸いです。

  1. WSL 1 と WSL 2 の比較 - docs.microsoft.com

  2. MicroK8s - Get started

  3. Addon:dashboard - MicroK8s

5
3
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
5
3