はじめに
k3sという軽量なKubernetes環境があるということで、Vagrantで構築してみました。
Vagrantで構築する場合、ネットワーク設定(flannel)で注意点があるため記録を残します。
構成
以下のように、3台のUbuntu 16.04マシンをそれぞれ、master, node1, node2として構成し、Node間はプライベートネットワークで接続します。
flannelのVXLANインターフェースが適切に設定されない問題
こちらのissueの通りですが、そのままインストールするとNode間の通信ができません。
k3sで使われているCNIのflannelはVXLANトンネルを利用してNode間通信を行います。その時に利用するVXLANの出入口となるNICがデフォルトではNodeの一番最初のNICとなります。
Vagrantの場合、必ずNAT用のNICが最初に作成されてしまうため、デフォルトではNAT用のインターフェースが選択されてしまい都合が良くありません。
kubeadm等で構築する場合は、flanneldの実行引数--iface
で明示的に指定可能ですが、k3sではflannelが組み込まれているため指定ができません。
そのため、今回はk3sでは--no-flannel
フラグを付けてflannelインストールをスキップし、別途flannelをインストールしました。
なお、k3sの実行オプションとして--flannel-iface
を付けるPRもあるため、取り込まれたらk3sのflannelを利用しても設定できるようになります。
--2019/4/26追記
マージされていました。
Master Nodeへk3sをインストール
公式のインストーラーを用いて以下のように設定します。INSTALL_K3S_EXEC
の環境変数を用いてオプションを渡してあげます。
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--no-flannel --node-ip=192.168.33.11" sh -
/var/lib/rancher/k3s/server/node-token
にNode追加用のトークンが払い出されていますので、メモしておきます。
Node1,2を追加
先ほどメモしたトークンを用いてNode1, 2をagentとして追加します。以下はNode1用です。
export K3S_TOKEN=<トークン>
export K3S_URL=https://192.168.33.11:6443
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--no-flannel --node-ip=192.168.33.12" sh -
CNIプラグインのインストール
すべてのNodeにおいて、CNIプラグインを配置しておく必要があるため、あらかじめ公式のリリースページよりcni-plugins-xxxx.tgz
をインストールし、/opt/cni/bin
に展開しておきます。
flannelをインストール
flannel自身のデプロイはkubectl
を使って行います。
公式のマニフェストファイルをダウンロードして、以下のように修正します。
ポイントは以下の2点です。
- flanneldのDaemonSetで起動オプションに
--iface
を追加- 以下の例は
amd64
用のDaemonSetに設定しましたが、環境にあわせて適切に設定してください。
- 以下の例は
- CNI設定のConfigMapを環境にあわせて設定
- k3sのデフォルトにあわせて
10.42.0.0/16
で設定しました。
- k3sのデフォルトにあわせて
--- kube-flannel.yaml.org 2019-03-21 09:28:45.427370300 +0000
+++ kube-flannel.yaml 2019-03-20 14:37:30.155241900 +0000
@@ -124,7 +124,7 @@
}
net-conf.json: |
{
- "Network": "10.244.0.0/16",
+ "Network": "10.42.0.0/16",
"Backend": {
"Type": "vxlan"
}
@@ -174,6 +174,7 @@
args:
- --ip-masq
- --kube-subnet-mgr
+ - --iface=enp0s8
resources:
requests:
cpu: "100m"
修正したファイルをkubectl
で適用します。
vagrant@master:~$ kubectl apply -f kube-flannel.yaml
確認
以上で構築は完了しました。VXLANインターフェースの設定やNode間通信が問題ないかを確認します。
VXLANインターフェース
vagrant@master:~$ ip -d a show flannel.1
4: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default
link/ether 6a:02:aa:4b:49:0d brd ff:ff:ff:ff:ff:ff promiscuity 0
vxlan id 1 local 192.168.33.11 dev enp0s8 srcport 0 0 dstport 8472 nolearning ageing 300
inet 10.42.0.0/32 scope global flannel.1
valid_lft forever preferred_lft forever
inet6 fe80::6802:aaff:fe4b:490d/64 scope link
valid_lft forever preferred_lft forever
プライベートのインターフェースが設定されています。
Node間通信
NginxのDeploymentを適当に作成しておきます。
vagrant@master:~$ kubectl run --image=nginx --replicas=5 nginx
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx created
vagrant@master:~$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7cdbd8cdc9-824qd 1/1 Running 0 25s 10.42.1.12 node1 <none> <none>
nginx-7cdbd8cdc9-9sct7 1/1 Running 0 25s 10.42.2.11 node2 <none> <none>
nginx-7cdbd8cdc9-bxfhb 1/1 Running 0 25s 10.42.2.12 node2 <none> <none>
nginx-7cdbd8cdc9-csd4p 1/1 Running 0 25s 10.42.1.13 node1 <none> <none>
nginx-7cdbd8cdc9-wcn9s 1/1 Running 0 25s 10.42.0.13 master <none> <none>
- Master -> Pods の通信
vagrant@master:~$ ping 10.42.1.12 -c 1
PING 10.42.1.12 (10.42.1.12) 56(84) bytes of data.
64 bytes from 10.42.1.12: icmp_seq=1 ttl=63 time=0.425 ms
--- 10.42.1.12 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.425/0.425/0.425/0.000 ms
vagrant@master:~$ ping 10.42.2.11 -c 1
PING 10.42.2.11 (10.42.2.11) 56(84) bytes of data.
64 bytes from 10.42.2.11: icmp_seq=1 ttl=63 time=0.802 ms
--- 10.42.2.11 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.802/0.802/0.802/0.000 ms
- Pod -> Pods の通信
vagrant@master:~$ kubectl run --generator=run-pod/v1 -it test --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # ping 10.42.0.13 -c 1
PING 10.42.0.13 (10.42.0.13): 56 data bytes
64 bytes from 10.42.0.13: seq=0 ttl=64 time=0.075 ms
--- 10.42.0.13 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.075/0.075/0.075 ms
/ # ping 10.42.1.12 -c 1
PING 10.42.1.12 (10.42.1.12): 56 data bytes
64 bytes from 10.42.1.12: seq=0 ttl=62 time=0.484 ms
--- 10.42.1.12 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.484/0.484/0.484 ms
/ # ping 10.42.2.11 -c 1
PING 10.42.2.11 (10.42.2.11): 56 data bytes
64 bytes from 10.42.2.11: seq=0 ttl=62 time=0.433 ms
--- 10.42.2.11 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.433/0.433/0.433 ms
すべて通信できることが確認できました。
Vagrantfile
最後に、すべてをまとめたVagrantファイルを以下に置いておきます。
kube-flannel.yaml
は修正済みのものがすでにVagrantfileと同じフォルダに置かれているものとします。
# -*- mode: ruby -*-
# vi: set ft=ruby :
$configureCommon = <<-SHELL
# apt-get update
# apt-get upgrade -y
## cni pluginsを展開
mkdir -p /opt/cni/bin
curl -sSL https://github.com/containernetworking/plugins/releases/download/v0.7.5/cni-plugins-amd64-v0.7.5.tgz | tar xzf - -C /opt/cni/bin
SHELL
$configureMaster = <<-SHELL
# プライベートネットワークのNICのIPアドレスを変数に格納
IPADDR=$(ip a show enp0s8 | grep "inet " | awk '{print $2}' | cut -d / -f1)
## k3sのデプロイ flannelをOFF プライベートIPをkubeletのIPとするように指定
## ここで、flannelをOFFにしているのは、現在ではVxLANの送出IFの指定ができず、Vagrant環境の場合、NATインターフェースが選択されてしまうため都合が悪い
## k3sのFlannelはあきらめて、flannelは別途構築する
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--no-flannel --node-ip=${IPADDR}" sh -
## flannelのデプロイ
kubectl apply -f /vagrant/kube-flannel.yaml
## agent登録用のトークンを共有フォルダに配置
cp /var/lib/rancher/k3s/server/node-token /vagrant/token
SHELL
$configureNode = <<-SHELL
export K3S_TOKEN=$(cat /vagrant/token)
export K3S_URL=https://192.168.33.11:6443
# プライベートネットワークのNICのIPアドレスを変数に格納
IPADDR=$(ip a show enp0s8 | grep "inet " | awk '{print $2}' | cut -d / -f1)
## k3sのデプロイ flannelをOFF プライベートIPをkubeletのIPとするように指定
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--no-flannel --node-ip=${IPADDR}" sh -
SHELL
Vagrant.configure(2) do |config|
node_num = 3
(1..node_num).each do |i|
if i == 1 then
vm_name = "master"
else
vm_name = "node#{i-1}"
end
config.vm.define vm_name do |s|
# ホスト名
s.vm.hostname = vm_name
# ノードのベースOSを指定
s.vm.box = "ubuntu/xenial64"
# ネットワークを指定
private_ip = "192.168.33.#{i+10}"
s.vm.network "private_network", ip: private_ip
# 共通
s.vm.provision "shell", inline: $configureCommon
if i == 1 then
# For Master
s.vm.provision "shell", inline: $configureMaster
else
# For Nodes
s.vm.provision "shell", inline: $configureNode
end
end
end
end