0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

wsl2のubuntuでk3sを動かしてみた

Posted at

始めに

wsl2のubuntuを使い始めて早数か月。ちょっとkubernates関連を調べたところ、今更ですが、軽量版k3sというものに突き当たり、動かしてみようと思いました。手っ取り早いのはraspberry piで動かすなのだと思いますが、せっかくなのでwsl2で動かしてみようかと思い、ググってみると、そう、wsl2 ubuntuではsystemdを使っていないのです。追いかけるとsystemdの入れ方もあるとのことで、k3sの簡単な動作確認までできたので、メモとして残します。
※ただ下にも書きましたが、systemdの動作があまり健全じゃないので、あくまでも実験と考えてください。

参考サイト

Running k3s on Windows with WSL2
主にここでの手順を使いました。

Running Snaps on WSL2 (Insiders only for now)
systemdの有効化の仕方が書いてあります。上のサイトからの参照。

ラズパイとJetson Nanoが混在したKubernetes環境をk3sで作る
k3sのインストールと動作確認の参考にしました。

前提(必要なもの)

  • Windows10 PCにwsl2 ubuntuがインストールされているもの

手順

  1. wsl2 ubuntuでsystemdを有効化する
    この部分は失敗すると最悪ubuntuが立ち上がらなくなります。事前にデータのバックアップを取るか、別途別バージョンとしてインストールした環境で行ってください。

(1) まずは必要ライブラリを入れます。多分最初から入っている場合もありますが、念のため。

$ sudo apt update
$ sudo apt install -yqq daemonize dbus-user-session fontconfig

(2) /usr/sbin/start-systemd-namespaceの作成
/usr/sbin/ に start-systemd-namespaceというファイルを作成します。

$ sudo vi /usr/sbin/start-systemd-namespace
/usr/sbin/start-systemd-namespace

# !/bin/bash

SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')
if [ -z "$SYSTEMD_PID" ] || [ "$SYSTEMD_PID" != "1" ]; then
    export PRE_NAMESPACE_PATH="$PATH"
    (set -o posix; set) | \
        grep -v "^BASH" | \
        grep -v "^DIRSTACK=" | \
        grep -v "^EUID=" | \
        grep -v "^GROUPS=" | \
        grep -v "^HOME=" | \
        grep -v "^HOSTNAME=" | \
        grep -v "^HOSTTYPE=" | \
        grep -v "^IFS='.*"$'\n'"'" | \
        grep -v "^LANG=" | \
        grep -v "^LOGNAME=" | \
        grep -v "^MACHTYPE=" | \
        grep -v "^NAME=" | \
        grep -v "^OPTERR=" | \
        grep -v "^OPTIND=" | \
        grep -v "^OSTYPE=" | \
        grep -v "^PIPESTATUS=" | \
        grep -v "^POSIXLY_CORRECT=" | \
        grep -v "^PPID=" | \
        grep -v "^PS1=" | \
        grep -v "^PS4=" | \
        grep -v "^SHELL=" | \
        grep -v "^SHELLOPTS=" | \
        grep -v "^SHLVL=" | \
        grep -v "^SYSTEMD_PID=" | \
        grep -v "^UID=" | \
        grep -v "^USER=" | \
        grep -v "^_=" | \
        cat - > "$HOME/.systemd-env"
    echo "PATH='$PATH'" >> "$HOME/.systemd-env"
    exec sudo /usr/sbin/enter-systemd-namespace "$BASH_EXECUTION_STRING"
fi
if [ -n "$PRE_NAMESPACE_PATH" ]; then
    export PATH="$PRE_NAMESPACE_PATH"
fi

(3) 同じように、/usr/sbin/enter-systemd-namespaceを作成します。

$ sudo vi /usr/sbin/enter-systemd-namespace

ここで、ubuntu-18.04とubuntu-20.04でdaemonizeのパスが違うという悲劇があります。
それぞれのバージョンの方をコピーしてください。

for_ubuntu-18.04__/usr/sbin/enter-systemd-namespace
# !/bin/bash

if [ "$UID" != 0 ]; then
    echo "You need to run $0 through sudo"
    exit 1
fi

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

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
    if [ -n "$1" ] && [ "$1" != "bash --login" ] && [ "$1" != "/bin/bash --login" ]; then
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /usr/bin/sudo -H -u "$SUDO_USER" \
            /bin/bash -c 'set -a; source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")"
    else
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /bin/login -p -f "$SUDO_USER" \
            $(/bin/cat "$HOME/.systemd-env" | grep -v "^PATH=")
    fi
    echo "Existential crisis"
fi
for_ubuntu-20.04__/usr/sbin/enter-systemd-namespace
# !/bin/bash

if [ "$UID" != 0 ]; then
    echo "You need to run $0 through sudo"
    exit 1
fi

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

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
    if [ -n "$1" ] && [ "$1" != "bash --login" ] && [ "$1" != "/bin/bash --login" ]; then
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /usr/bin/sudo -H -u "$SUDO_USER" \
            /bin/bash -c 'set -a; source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")"
    else
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /bin/login -p -f "$SUDO_USER" \
            $(/bin/cat "$HOME/.systemd-env" | grep -v "^PATH=")
    fi
    echo "Existential crisis"
fi

動作モードを変更します。

$ sudo chmod +x /usr/sbin/enter-systemd-namespace

(4) visudoで設定を変更します。

$ sudo visudo

ファイルの最後に以下を追加します。

visudoで開くファイル
Defaults        env_keep += WSLPATH
Defaults        env_keep += WSLENV
Defaults        env_keep += WSL_INTEROP
Defaults        env_keep += WSL_DISTRO_NAME
Defaults        env_keep += PRE_NAMESPACE_PATH
%sudo ALL=(ALL) NOPASSWD: /usr/sbin/enter-systemd-namespace

ここでエディターがnanoが嫌だー、viがいい! という人は先に以下を実行してください。

$ sudo update-alternatives --set editor /usr/bin/vim.basic

(5) デフォルトのbashrc変更します。

$ sudo sed -i 2a"# Start or enter a PID namespace in WSL2\nsource /usr/sbin/start-systemd-namespace\n" /etc/bash.bashrc

(6) windows側に環境変数を追加します。ここはwindows10のpowershell(管理者権限)で下記コマンドを実行します。その後、wsl2をシャットダウンして再立ち上げします。

PowerShell
> cmd.exe /C setx WSLENV BASH_ENV/u
> cmd.exe /C setx BASH_ENV /etc/bash.bashrc
> wsl --shutdown

再びwsl2 ubuntuのコンソールを立ち上げ、systemdで立ち上がっているかを確認します。

$ sudo systemctl status

systemd以下のツリーが表示されます。ただ、レッドシグナルとなり、きちんと動いていない雰囲気です・・・。

  1. Dockerのインストール

aptでインストールして、systemctlで起動します。

$ sudo apt install docker.io
$ sudo systemctl start docker
$ sudo systemctl enable docker

各種設定あると思いますが、実験なので省略します。
あと、動作アプリとしてnginxを使用するので、インストールします。

$ sudo apt install nginx
  1. k3sのインストール

k3sはwsl2上でmaster nodeとworker nodeを立ててしまいます。
ここからは、このサイトを参考にします。

$ curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--docker" sh -s -

確認をします。

$ sudo kubectl get nodes

nameを記録しておきます。ここでは仮にubuntuにします。
以下のファイルを作成します。

nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginxapp1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginxapp1
  template:
    metadata:
      labels:
        app: nginxapp1
    spec:
      containers:
      - name: nginxapp1
        image: nginx:alpine
        ports:
        - containerPort: 80
      nodeSelector:
        kubernetes.io/hostname: ubuntu

最後の行のubuntuの部分を先ほどのnameにします。
nginx.yamlを実行します。podができていることを確認します。

$ sudo kubectl create -f nginx.yaml
$ sudo kubectl get pods

次にサービスのyamlを作成します。

nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginxapp1-nodeport
  labels:
    app: nginxapp1
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
  selector:
    app: nginxapp1

実行してサービスを作ります。確認もします。

$ sudo kubectl create -f nginx-svc.yaml 
$ sudo kubectl get services

これで、サービスが立ち上がっているはずです。master nodeの30080ポートをアクセスすると、nginxの初期画面を見ることができます。ifconfigなどで、wsl2 ubuntuのIPアドレスを取得して、windows上のブラウザでアクセスするとみることができます。
あとは、dockerで適当なテストを作ってみると良いと思います。

最後に

もっとすっきりとsystemdが動いてくれたらよかったのですが、ちょっと手に負えないのでしばらく様子を見て、直せたら直してみようと思います。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?