仮想化通信

日本仮想化技術株式会社の公式エンジニアブログ

UbuntuでCRI-OをKubernetesで使う

UbuntuベースでコンテナーランタイムのCRI-Oをインストールして、kubeadmを使ってKubernetesをデプロイしたときの記録です。 ドキュメントも揃っているし、鼻をほじりながらでもできるのでは?と思っていたら、思っていた以上に大変でした。

初期設定

まずは最低限必要なこと。 Ubuntu Serverをインストールします。今回はUbuntu 18.04.3をインストールしました。インストール後、IPアドレスを設定したり、アップデートを実行しておきます。 今回はOpenStackのインスタンスで動かしたので、インスタンスを起動したあとにFlating IPアドレスを振りました。

その後、Kubernetes公式のドキュメントに従って、CRI-Oをインストールします。

kubernetes.io

最後に「Start CRI-O」と言うステップがあります。ここで起動しないでもとりあえず良しとしておいてください。

# systemctl daemon-reload
# systemctl start crio

CRI-Oの設定変更

CRI-Oの設定を初期設定からいくつか変更します。

conmonのパスが現在の最新バージョンだと変わっているので変更します。 network_dirにはCRI-Oのブリッジインターフェイスの設定をおいておく必要がありますが、デフォルトの /etc/cni/net.d/kubeadm reset を実行するとクリーンアップしてしまうので、CRI-O関連のネットワーク設定関連はそことは別のパスに置くように変更します。

# vi /etc/crio/crio.conf
...
#conmon = "/usr/libexec/crio/conmon"
conmon = "/usr/bin/conmon"
...

[crio.network]
#network_dir = "/etc/cni/net.d/"
network_dir = "/etc/cni/crio/net.d/"
...
#最終行に追記
[registries.search]
registries = ['docker.io', 'registry.fedoraproject.org', 'registry.access.redhat.com']

[同日追記]

ディレクトリーを作るステップを書くのを忘れていました。

# mkdir -p /etc/cni/crio/net.d/

CRI-Oブリッジの作成

2つのファイルを作ります。サブネットはKubernetesをデプロイしたあと、導入するCNIの要件にあったものを指定します。例えばFlannelやCanalの場合は 10.244.0.0/16 です。

# vi /etc/cni/crio/net.d/10-crio-bridge.conf
{
    "cniVersion": "0.3.1",
    "name": "crio-bridge",
    "type": "bridge",
    "bridge": "cni0",
    "isGateway": true,
    "ipMasq": true,
    "hairpinMode": true,
    "ipam": {
        "type": "host-local",
        "routes": [
            { "dst": "0.0.0.0/0" },
            { "dst": "1100:200::1/24" }
        ],
        "ranges": [
            [{ "subnet": "10.244.0.0/16" }],
            [{ "subnet": "1100:200::/24" }]
        ]
    }
}


# vi /etc/cni/crio/net.d/99-loopback.conf
{
    "cniVersion": "0.3.1",
    "type": "loopback"
}

CRI-Oの再起動

設定を反映させるために daemon-reload を実行し、その後CRI-Oサービスを再起動します。 statusを見ると、CRI-Oがきちんと起動したはずです。

# systemctl daemon-reload
# systemctl restart crio

kubeadmなどのインストール

kubeadm、kubelet、kubectlはデプロイしたいKubernetesのバージョンにあったものをインストールします。 今回インストールしたCRI-Oは1.15でした。 CRI-Oはn-1の互換性を保証しています。このため、インストールできるKubernetesは1.15か1.16になります。

現在、公式のCRI-Oパッケージのリポジトリーを変更する動きが起こっています。おそらく準備完了次第ドキュメントの手順が更新され、CRI-O 1.17を使えばKubernetes 1.17も利用可能になると思われます。

今回はCRI-O 1.15 + Kubernetes 1.16な構成をkubeadmで構築します。 というわけで、バージョン1.16のkubeadm、kubelet、kubectlをインストールします。

まず、リポジトリーの追加から。

# apt update && apt install -y apt-transport-https curl
# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
# cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF

次にkubeletなどをインストールします。

基本的には公式の手順通りですが、バージョンを指定する必要があるので、こんな感じで実行します。

現在公開されているバージョンを確認します。

# apt update
# apt list -a  kubelet kubeadm kubectl

1.16.4-00 というバージョンをインストールする場合は、次のように実行します。

# apt install -y kubelet=1.16.4-00 kubeadm=1.16.4-00 kubectl=1.16.4-00

アップグレードされないようにバージョンをロックします(バージョンロックを解除するには apt-mark hold 〜 を実行します。)。

# apt-mark hold kubelet kubeadm kubectl

kubeletの設定を追記

公式の情報を参考にして、cgroup-driverの設定やコンテナーランタイムを指定します。

# vi /etc/default/kubelet
KUBELET_EXTRA_ARGS=--cgroup-driver=systemd --container-runtime=remote --container-runtime-endpoint="unix:///var/run/crio/crio.sock"

変更した構成を適用するために実行します。

# systemctl daemon-reload

kubeadmでクラスターを作成

kubeadmを使って、Kubernetes クラスターを構築します。 今回はバージョン1.16.4-00のKubeadmをインストールしたので、kubernetes-versionで1.16.4を指定してます。pod-network-cidrはCNIで必要なcidrを指定します。control-plane-endpointはKubernetes API endpointで利用したいIPアドレスなどを指定します。今回はOpenStackインスタンスで動かしたため、Floating IPアドレスを指定しました。

# kubeadm init --kubernetes-version 1.16.4 --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=172.16.214.167

エラーが発生して失敗したら、kubeadm resetを実行します。問題が起きなかった場合は画面の指示に従い、kubeconfigの設定や、複数台構成にする場合は kubeadm join 、MasterノードでWorkerプロセスを実行する(もしくはシングルノードで実行したい)場合は、次のコマンドを実行します。

# kubectl taint nodes --all node-role.kubernetes.io/master-

CNIのセットアップ

このあと、CNIをセットアップします。 今回はFlannelを想定してpod-network-cidrを設定したので、Flannelをセットアップします。

(2020/01/16現在)

# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml

使ってみる

KubernetesでPodを作り、アプリケーションコンテナーを動かしてみましょう。

~# cat hello-ubi8.yaml
apiVersion: v1
kind: Pod
metadata:
  name: hello-ubi8
spec:
  containers:
    - name: hello-ubi8
      image: registry.access.redhat.com/ubi8-minimal
      tty: true

~# kubectl create -f hello-ubi8.yaml

~# kubectl get no
NAME         STATUS   ROLES    AGE   VERSION
crio-demo3   Ready    master   26m   v1.16.4

~# kubectl get po

NAME            READY   STATUS    RESTARTS   AGE
hello-ubi8      1/1     Running   0          4m44s

うまくいきました。 ps aux|grep crio を実行すると複数のプロセスが動いていることが確認できます。

参考にした情報

参考になった情報は以下のものです。特に一番最初のブログは役立ちました。