kubernetes上で自作コンテナランタイムを動かしてみた...けど間に合わなかった話

この記事は[Kubernetes3 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/kubernetes3)の19日目の記事です。

#はじめに
タイトルの通りこの記事はkubernetes上で自作コンテナランタイムを利用してコンテナを動かそうと思ったけど、そもそも完成に全然間に合わずまともに動かなかった話となります。

本来であれば自作コンテナランタイムを完成させた上で動かしてみた話を投稿できればと思っていたのですが、正直全然間に合いませんでした...。

成功しているわけではないので投稿するには微妙な話かもしれませんが
折角挑戦してみたので投稿しないのももったいないと思い投稿する事にしました。

#何故作ろうと思ったのか
一言で言うと面白そうだと思ったからです。
きっかけは[コンテナ型仮想化の情報交換会](https://ct-study.connpass.com/)に参加させて頂いて自作コンテナを作られている型の話を聞いたのがきっかけです。
参加した時はDockerに興味があるぐらいでしたが、自作されている話を実際に聞いてみて簡単なものなら作るのはそう難しくない事をしり、やってみようと思いました。

#自作コンテナランタイムについて
Rustで作っています。

#概要
実際に行った内容は
1. kubernetesのruntimeをDockerからcri-oに変更
2. cir-oが内部で利用するruntimeを自作のものに変更
となります。

#環境
OS:Ubuntu18.04
Kubernetes:1.13
Rust.1.31

#cri-oのインストール
`cri-o`のインストール・設定に関しては[cri-oのTutorial](https://github.com/kubernetes-sigs/cri-o/blob/master/tutorial.md)と[アドテクさんの記事](https://adtech.cyberagent.io/techblog/archives/4036)を参考にさせて頂きました。基本的に上記記事の設定方法を元にさせて頂いていますので、もしこの記事を読んで少しでも興味を持って頂ける方がおられたら、そちらも見て頂ければと思います。

それでは実際にインストールを行っていきます。

まずは`cri-o`のインストールの前に`Go`をインストールします。
公式の`cri-o`のTutorialでは`Go`の1.8.5のバイナリを取得する様になっていますが、2018/12/19現在 1.8.5ではその後の処理が進まなくなりますので、最新のバージョンのバイナリを取得します。

```shell:Goのインストール
wget https://dl.google.com/go/go1.11.4.linux-amd64.tar.gz
sudo tar -xvf go1.11.4.linux-amd64.tar.gz -C /usr/local/
mkdir -p $HOME/go/src
export GOPATH=$HOME/go
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
go version
# go version go1.11.4 linux/amd64
```
これで`Go`のインストールができました。

次にCRIのclientである`crictl`をインストールします。
上記でGoの最新バージョンを取得していますが、1.8.5を取得している場合は`crictl`のインストールでエラーとなります。
どうも`crictl`が依存しているソースの中に1.10以降のAPIを使用していたりするものがあるようです。

```shell:crictlのインストール
go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
# 1.8.5だとここでエラーが発生します。
cd $GOPATH/src/github.com/kubernetes-incubator/cri-tools
make
make install
```

`circtl`のインストールまで終わったら、`cri-o`のインストールに入ります。
`cri-o`はバイナリを提供していませんので、依存するパッケージ等を取得した後にソースからビルドして`cri-o`をインストールします。

```shell:cri-oのインストール
# 必要なパッケージの取得
sudo apt-get update && apt-get install -y libglib2.0-dev \
                                          libseccomp-dev \
                                          libgpgme11-dev \
                                          libdevmapper-dev \
                                          make \
                                          git
go get -d github.com/kubernetes-sigs/cri-o
cd $GOPATH/src/github.com/kubernetes-sigs/cri-o
make install.tools
make
sudo make install
```
これでやっと`cri-o`のインストールが完了となります。

#cri-oの設定
`cri-o`のインストールが完了したら`cri-o`が使用する設定ファイルを下記コマンドで作成します。

```shell:cri-oの設定ファイル作成
sudo make install.config
```

DockerHubからイメージを取得できるように設定ファイルの中身を書き換えます。
(最初はコメントアウトされています)

```shell:/etc/crio/crio.conf
# 自作コンテナランタイムを設定
default_runtime = "minicon"
# コメントアウトを外してDockerHubを設定
registries = ['docker.io']
```

`cri-o`をsystemdから動かす為に設定を行います。

```shell:systemdの設定
sudo sh -c 'echo "[Unit]
Description=OCI-based implementation of Kubernetes Container Runtime Interface
Documentation=https://github.com/kubernetes-sigs/cri-o

[Service]
ExecStart=/usr/local/bin/crio
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/crio.service'

sudo systemctl daemon-reload
sudo systemctl enable crio
sudo systemctl start crio
```

`cri-o`の設定はこれで終わりです。

#kubeletの設定
`cri-o`のインストール設定が終わりましたので、`kubelet`から`cri-o`を利用できるように下記オプションを指定して再起動します。

```shell:kubeletの再起動
--container-runtime=remote
--container-runtime-endpoint=/var/run/crio/crio.sock
```

`kubelet`が問題なく起動すれば全ての設定が終了となります。

#Podの起動
設定が全て終わりましたので、実際にPodの起動を試みてみます。（間違いなく失敗しますが...）
下記のyamlファイルを適用してPodを作成します。

```yaml:pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx-container
      image: nginx
      ports:
      - containerPort: 80
```

```shell:Podの作成
kubectl create -f pod-nginx.yaml

The connection to the server 172.31.24.225:6443 was refused - did you specify the right host or port?
```
はい、Podの起動に失敗しました...。そもそも未完成なので当たり前ですね。

#終わりに
予想通り自作コンテナランタイムの起動に失敗しました。
冒頭にも記載している通り間に合えばよかったのですが、私自身システムプログラミングは初挑戦なので勉強しながら作っている為、全然進まなかったのでこんな記事になってしまいました。

こんな記事ですが何かの役にたてば幸いです。