自宅のiMac上にKubernetesの環境を作ってみたときの覚え書き。
使用した環境
- iMac (Retina 5K, 27-inch, 2017)
- macOS Catalina 10.15.2 (16GB)
- VMWare Fusion Pro 11.5.1
- GuestOS: Ubuntu Server 18.04
VMWare Fusionについて
独自の仮想ネットワークを作成する場合、VMWare FusionだとPro版が必要となります。VMWare Fusion以外だとVirtualBoxが仮想ネットワークの作成が行えます。
想定しているネットワーク構成はこんな感じ。
Kube(node1)のNICが片方しかないのは、Kubernetesの内部ルーティングの動作を確認したい為です。

Linux自体の環境設定
たいしたことはしていないのですが、ネットワーク設定をしておきます。
まず、VMWareは標準でDHCPによる割り振りがされてしまう為、VM内のホストにはそれぞれ固定IPアドレスを設定しておきます。
- master
- ens33: DHCP (ex: 172.16.42.131)
- ens34: 192.168.110.128
- node1
- ens33: 192.168.110.129
- node2
- ens33: DHCP (ex: 172.16.42.132)
- ens34: 192.168.110.130
# Kube(node01)の例 network: version: 2 ethernets: ens33: dhcp4: false addresses: - 192.168.110.129/24 gateway4: 192.168.110.128 nameservers: addresses: [172.16.42.2]
master側
masterはクラスタのルーティングを兼ねている為、以下の設定をしておきます。これをやらないとnode1は外部と通信が出来ません。
sudo iptables -A FORWARD -i ens33 -j ACCEPT sudo iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.110.0/24
保存する場合は aptitude install iptables-persistent
で、netfilter-persistent を導入することで保存が出来るようになります。
netfilter-persistent save
で保存が出来るようになります。
この時点でのiptablesの設定はこんな感じです。Docker関係の項目はDockerが起動する際に追加される項目です。
# Generated by iptables-save v1.6.1 *filter :INPUT ACCEPT [472:50670] :FORWARD ACCEPT [476:28584] :OUTPUT ACCEPT [290:35406] :DOCKER - [0:0] :DOCKER-ISOLATION-STAGE-1 - [0:0] :DOCKER-ISOLATION-STAGE-2 - [0:0] :DOCKER-USER - [0:0] -A FORWARD -j DOCKER-USER -A FORWARD -j DOCKER-ISOLATION-STAGE-1 -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -o docker0 -j DOCKER -A FORWARD -i docker0 ! -o docker0 -j ACCEPT -A FORWARD -i docker0 -o docker0 -j ACCEPT -A FORWARD -i ens33 -j ACCEPT -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2 -A DOCKER-ISOLATION-STAGE-1 -j RETURN -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP -A DOCKER-ISOLATION-STAGE-2 -j RETURN -A DOCKER-USER -j RETURN COMMIT # Completed # Generated by iptables-save v1.6.1 *nat :PREROUTING ACCEPT [458:27778] :INPUT ACCEPT [1:334] :OUTPUT ACCEPT [12:929] :POSTROUTING ACCEPT [12:929] :DOCKER - [0:0] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE -A POSTROUTING -s 192.168.110.0/24 -j MASQUERADE -A DOCKER -i docker0 -j RETURN COMMIT # Completed
Kubernetes 1.17.2のセットアップ
セットアップはubuntu 18.4環境にDockerをインストールし、kubeadmで行います。この方法は時代遅れなのかもしれませんが、今のところ自分が慣れているのがこの方法ですので、以下のマニュアルに倣って行います。
- Dockerのインストール方法
- kubeadm, kubectl, kubeletのインストール方法
- clusterのセットアップ方法
ubuntu 18.04であれば、記載されている手順通りに行えばセットアップは完了します。
ubuntu18.04では標準でiptablesがインストールされているのですが、それ以外のシステムを使用している場合はインストールが行えません。また、ubuntu 18以降のバージョンにおいても iptables とは別のシステムとなる予定だそうです。
これについては、インストールマニュアルの注意を読んでください。
すべてのノードにDocker、kubeadm, kubectl, kubeletのインストールが完了したら、Kubernetesのmasterをセットアップします。
自分は以下のコマンドで行いました。
kubeadm init --apiserver-advertise-address=192.168.110.128 --pod-network-cidr=192.168.0.0/24
ここで –apiserver-advertise-address を指定していますが、これは誤ったNICをAPIServerにしない為です。
NICが複数存在している場合、意図しないものがKubernetesのAPI Server向けに設定されてしまう事がある為、ここでは –apiserver-advertise-address で明示的に指定します。
セットアップが完了すると、設定ファイルをコピーする様に促されますので指示通りに保存します。
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
設定ファイルをコピーしたら kubectl get pods -n kube-system で起動状態を確認出来ます。おそらくこのような状態になっています。
NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-6955765f44-fnpv6 0/1 Pending 0 95s kube-system coredns-6955765f44-wdh6x 0/1 Pending 0 95s kube-system etcd-k8s-master 1/1 Running 0 90s kube-system kube-apiserver-k8s-master 1/1 Running 0 90s kube-system kube-controller-manager-k8s-master 1/1 Running 0 90s kube-system kube-proxy-vhm6l 1/1 Running 0 95s kube-system kube-scheduler-k8s-master 1/1 Running 0 89s
coredns が Pending 状態になっていますが、これは Kubernetes 内の network 設定が完了しないと開始しないようにマニフェストが記述されている為に生じているので、この時点では正常です。
network設定には幾つかの選択肢がありますが、ここではcalicoを利用します。
calicoのインストール
calicoは環境にあわせて設定を変更する必要がありますので、まずはマニフェストをローカルにダウンロードます。(Kubernetesのマニュアル通りに実行すると正しく動作しません。calicoのドキュメントを読みながら実行するか、以下の様にCIDRを書き換えてください)
# calico.yamlをダウンロード cd /tmp curl https://docs.projectcalico.org/v3.8/manifests/calico.yaml -O # CALICO_IPV4POOL_CIDRの項目を修正 # kubeadm init で指定したCIDRと同じ物を設定 vi calico.yaml # 設定を反映 kubectl apply -f calico.yaml
再度 kubectl get pods -n kube-system で確認すると、calico関係のpodが追加されて、corednsもRunningに変わっているはずです。
ノードの追加
ノードの追加方法は、以下のコマンドで表示されるtokenを追加したいノード上で行うだけです。
kubeadm token create --print-join-command
手元の環境では、以下の様なコマンドが表示されます。
kubeadm join 192.168.110.128:6443 \ --token rmlcib.hoff0zcbxcsu19pb \ --discovery-token-ca-cert-hash sha256:f58b4c56b983b3df8b4ecdf666ebb12c0a20e0afc28aac9ee7c704568ceb5287
それぞれのノード上でkubeadm joinを行ってからしばらく待つと
NAME STATUS ROLES AGE VERSION k8s-master Ready master 10m v1.17.2 k8s-node01 Ready <none> 4m14s v1.17.2 k8s-node02 Ready <none> 2m40s v1.17.2
すべてのノードが追加されてReady状態となりました。
podをNICに結びつけてみる
これでKubernetesの設定自体は完了しているのですが、ちょっとしたテストをしてみます。
Kube(node01)は、192.168.110.0/24 のネットワークにしか所属していないため、このままではVMWareのホストである iMac と通信が出来ません。
ですが、KubernetesはPODとの通信をする方法が幾つか用意されており、それらの方法を使用すると、外部と通信が出来るようになります。
ここではウェブサーバーを組み込んだPODを起動して、Kube(master)やKube(node02)のNIC経由でアクセスしてみることにします。
ここでは試しにphpinfoを表示するだけのpodを作成してみました。
apiVersion: v1 kind: Pod metadata: name: testweb labels: component: web spec: containers: - name: testweb image: php:7.3-apache ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /var/www/html volumes: - name: config-volume configMap: name: testweb-phpcode nodeSelector: kubernetes.io/hostname: k8s-node01 --- apiVersion: v1 kind: ConfigMap metadata: name: testweb-phpcode data: index.php: | <?php phpinfo(); ?> --- apiVersion: v1 kind: Service metadata: name: testweb-port spec: selector: component: web ports: - name: http protocol: TCP port: 8080 targetPort: 80 externalIPs: - 172.16.42.131
externalIPsは、Kube(master)かKube(node02)が持っているIPAddressを設定してください。
このマニフェストファイルを、webserver.yamlという名称で保存したら、以下の様にしてKubernetesにpodを立ち上げてください。
kubectl apply -f webserver.yaml
マニフェストファイルに nodeSelector があるため、必ずKube(node01)で起動されます。一見通信が出来ない様にみえますが、 Kubernetes 内でうまくルーティングされて externalIPs にアクセスするとPODにつないでくれます。
上の例ですと、172.16.42.131:8080にブラウザでアクセスすると、phpinfoの画面が開きます。
リセットする場合
kubeadm reset でリセットしてやり直すことが出来ますが、リセットされるのは Kubernetes 本体のみとなります。その他の部分についてはそれぞれ個別にリセットが必要となります。
- /etc/cni/net.d の削除
- iptables の初期化(Calicoがiptablesに変更を加えていますが、再起動すれば消えます)
- modprobe -r ipip(Calicoはtunl0というNICを作成して、ノード間接続を実現しているのですが、このNICは kubeadm resetをしても消えませんので、手動で削除する必要があります)