クラウド環境の勉強と開発環境のセットアップを兼ねてKubernetesをインストール&セットアップします。
dockerをコンテナに使った情報ばかり出回ってますが、この記事では次世代を担うと思われる(個人的に)CRI-Oをコンテナランタイムとして採用しました。
インストール前の環境(サーバー、OS)
クラウド環境向けに安いPCを買ったので合計4台のリッチな環境でセットアップします。(Master 1台 + Worker Nodes 3台)
最終構成はkubernetesのサイトにある図と同じ構成になります。
コントロール(Master)用PC (Intel NUC) x 1台
コントロール用のMaster PCは、普段から使ってるデスクトップPCです。機種の詳細は別のブログ記事を参照してください。

超小型PC(Intel NUC)のLinux系の開発環境構築記事です。第一回目はOSインストールです。デュアルブート環境にします!
OS: Ubuntu 20.04 LTS (Desktop)
Kuberetes Nodes向けPC (Chuwi Herbox) x 3台
安い割にパフォーマンスが良いと評判だったので3台衝動買いしたChuwi HeroboxというミニPCです。機種の詳細は別のブログ記事を参照してください。

超小型ミニPCのHerobox。届いたのにレビュー記事書いてなかったので今更ですが書いていきます! HeroBoxはミニPCで有名なCHUWI
OS: Ubuntu 20.04 LTS (Server)
Kubernetes+cri-oセットアップ
今回は台数も多いのでAnsibleを使ってインストール部分は半自動で終わらせました。
手順としては、k8sのサイトにある手順通りにやればほぼ問題なく終わりました。
参考サイト(kubernetes.io)
参考サイトと手順は以下のようになります。
web Container runtimes - Kubernetes
最初に全ノード(Master + Worker Nodes)にコンテナランタイムをインストールします。
今回はCRI-Oをインストールしました。
web Installing kubeadm - Kubernetes
次に全ノードにkubeadm,kubelet,kubectlをインストールします。
web Creating a single control-plane cluster with kubeadm - Kubernetes
kubeadm init
して、インストール後作業して、pod networkの設定をして、workerノードを登録して終了です。
作業ログ:事前作業
では、実際の作業記録を見ていきます。
ssh環境セットアップ
事前作業としては、Master(コントロール用)ノードからWorkerノードに対してパスワードなしでsshログインできるようにセットアップする必要があります。
ssh-copy-id hoge@xxx.yyy.zzz
Master(コントロール)ノードの公開鍵をssh-copy-id
コマンドでworkerノードにコピーします。
swap利用ストップ
また、swapの設定があると動作しないので止めます。二通りのやり方があります。
- swapoff -a (リブートするともとに戻る)
- /etc/fstabからswapの行をコメントアウト
作業ログ:cri-oインストール
webの手順通りになるようにansibleのplaybookを作って全ノードに実施します。
---
- hosts: all
become: yes
become_user: root
tasks:
- name: modprobe overlay for crio
modprobe:
name: overlay
state: present
- name: modprobe br_netfilter for crio
modprobe:
name: br_netfilter
state: present
- name: check 99-kubernetes-cri.conf
stat:
path: /etc/sysctl.d/99-kubernetes-cri.conf
register: chk_file
- name: put 99-kubernetes-cri.conf
blockinfile:
path: /etc/sysctl.d/99-kubernetes-cri.conf
owner: root
group: root
mode: '0644'
create: yes
block: |
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
when: chk_file.stat.exists == False
- name: start sysctl
command: sysctl --system
- name: init crio repo
shell: >-
. /etc/os-release;
sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${NAME}_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list";
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/x${NAME}_${VERSION_ID}/Release.key -O- | sudo apt-key add -;
- name: apt update
apt:
update_cache: yes
- name: apt upgrade
apt:
name: "*"
state: latest
- name: install crio
apt:
name: cri-o-1.17
- name: start crio
systemd:
name: crio
state: started
daemon_reload: yes
ansible playbook
kubernetesのウェブにあった手順をそのままコマンドにしただけです。これでcri-oインストールは完了です。
作業ログ: kubeadm,kubelet,kubectlをインストール
次にkubeadm等のインストールですがこれもwebの手順をそのままansibleで実行します。
---
- hosts: all
become: yes
become_user: root
tasks:
- name: modprobe br_netfilter for crio
modprobe:
name: br_netfilter
state: present
- name: check /etc/sysctl.d/k8s.conf
stat:
path: /etc/sysctl.d/k8s.conf
register: chk_file
- name: put /etc/sysctl.d/k8s.conf
blockinfile:
path: /etc/sysctl.d/k8s.conf
owner: root
group: root
mode: '0644'
create: yes
block: |
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
when: chk_file.stat.exists == False
- name: start sysctl
command: sysctl --system
- name: apt update
apt:
update_cache: yes
- name: apt upgrade
apt:
name: "*"
state: latest
- name: install transport-https,curl
apt:
pkg:
- apt-transport-https
- curl
- name: init k8s repo
shell: >-
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -;
- name: check kubernetes.list
stat:
path: /etc/apt/sources.list.d/kubernetes.list
register: chk_file
- name: put kubernetes.list
blockinfile:
path: /etc/apt/sources.list.d/kubernetes.list
owner: root
group: root
mode: '0644'
create: yes
block: |
deb https://apt.kubernetes.io/ kubernetes-xenial main
when: chk_file.stat.exists == False
- name: apt update
apt:
update_cache: yes
- name: install k8s
apt:
pkg:
- kubelet
- kubeadm
- kubectl
- name: apt-mar k8s
shell: >-
apt-mark hold kubelet kubeadm kubectl;
ansible playbook
作業ログ: インストール後の設定作業
インストールした後はkubeadm init
で初期のコンフィグレーション作成等をするのですが、crioの場合いくつか事前にいじらないとうまく動かなかったので書いておきます。
/etc/crio/crio.conf
ファイルのcgroup_managerをsystemd指定にしておく(全ノード)
cgroup_manager = "systemd"
/etc/crictl.yaml
にもcgroup-manager: systemdを設定しておく(全ノード)
runtime-endpoint: unix:///var/run/crio/crio.sock
cgroup-manager: systemd
/etc/default/kubelet
を作成して以下を入れます(全ノード)
KUBELET_EXTRA_ARGS=--cgroup-driver=systemd --container-runtime-endpoint='unix:///var/run/crio/crio.sock'
ここまで設定したら一旦crioとkubeletをリスタートさせておきましょう。
$sudo systemctl daemon-reload
$sudo systemctl restart crio
$sudo systemctl restart kubelet
また、/etc/cni/net.d/100-crio-bridge.conf
を確認してデフォルトのpodネットワークアドレスを記録しておきます。
"ipam": {
"type": "host-local",
"routes": [
{ "dst": "0.0.0.0/0" },
{ "dst": "1100:200::1/24" }
],
"ranges": [
[{ "subnet": "10.88.0.0/16" }],
[{ "subnet": "1100:200::/24" }]
]
}
今回の環境の場合10.88.0.0/16
でした
作業ログ: インストール後の設定作業2
ここまでできたらpodネットワークのアドレスを指定してkubeadm init
を実行します。
sudo kubeadm init --pod-network-cidr=10.88.0.0/16
initが終わると最後の方にあれしろ、これしろと書かれているので順番に実施します。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
次にpodネットワークadd-onを選んでインストールします。この記事ではパフォーマンスに優れているという噂のcalicoを使います。
kubectl apply -f https://docs.projectcalico.org/v3.14/manifests/calico.yaml
最後に、各workerノードで登録用のコマンド(kubeadm initのログの最後にでてくる)を使ってworkerノードを登録していきます。
sudo kubeadm join 192.168.0.xxx:6443 --token 3434334343434344 \
--discovery-token-ca-cert-hash sha256:23232322342342...
きちんと登録できたかMasterノードで確認しましょう
heisaku@master:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 9m20s v1.18.3
worker1 Ready <none> 2m55s v1.18.3
worker2 Ready <none> 73s v1.18.3
worker3 Ready <none> 15s v1.18.3
無事セットアップできました。遊びがいがありそうですね。
最後にチュートリアルをやりましょう
この状態でクラスターは出来上がっているので、Kubernetesのチュートリアルに沿ってコマンドを実行して勉強しましょう。
web Kubernetesの基本を学ぶ - Kubernetes
enjoy!