Kubernetes 1.17.2 の環境構築メモ

タグ:

自宅の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で行います。この方法は時代遅れなのかもしれませんが、今のところ自分が慣れているのがこの方法ですので、以下のマニュアルに倣って行います。

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をしても消えませんので、手動で削除する必要があります)