Raspberry Piでkubernetesクラスタを組む

テクノロジー

はじめに

 サイオステクノロジー 中島です。

 本記事では、Raspberry pi3 B+とRaspberry pi4を組み合わせてkubenetesネットワークを作り、nginxで動作確認できるまでを確認します。

 なお、本記事の構成として、Raspberry pi3 B+をホストにRaspberry pi4をワーカーとしてkubernetesクラスタを作ります。

構築方法

 マスター装置とワーカー装置の構築方法について説明します。

 以下に装置構成図を示します。

 マスター装置とワーカー装置の構築で共通で行う作業については以下の作業を行いますが、

 本記事では、raspberrypi OSのインストール方法やssh接続の設定、無線LANの設定、パスワードの変更方法については説明を省略します。

  1. ホスト名の変更
  2. IPアドレスの固定
  3. hostsファイルへ追加
  4. Dockerのインストール
  5. Swapの設定をOFF
  6. IPフォワードの設定
  7. cgroupの有効
  8. kubernetesのコマンドインストール

 以上の構築作業がすべての機器で終わりましたら、kubernetesクラスターを作成し、そのクラスタ内でnginxが動作することを確認します。

ホスト名の変更

 本資料は、マスターとなる機器の名前を「k8s-master」にワーカーとなる機器の名前を「k8s-worker-1」とします。

 ホスト名設定ツールとして、raspi-configツールを使用して名前を変更しますので、以下のコマンドを実行します。

$ sudo raspi-config

「Network Options」->「Hostname」と選択します。そのあとの注意書きを「OK」を選択後の入力画面で、名前を入力し「OK」を選択します。以上でホスト名の変更が完了です。

IPアドレスの固定

 無線LANの接続IPを固定します。

 マスターとなるアドレスを「192.168.0.24」、ワーカーとなるアドレスを「192.168.0.25」とします。

 設定方法は以下コマンドを実行して

$ sudo vi /etc/dhcpcd.conf

 上記コマンド実行後末尾に、以下の文字列を追加します。

interface wlan0
static ip_address=192.168.0.24/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1

hostsファイルへ追加

 /etc/hostsに以下の設定を追加する。

192.168.0.24     k8s-master
192.168.0.25     k8s-worker-1

 このファイルを設定すると、k8s-masterでk8s-worker-1にsshなどで、アクセスする際に「k8s-worker-1.local」でも、「k8s-worker-1」でもアクセスできるようになります。

Dockerのインストール

 以下のコマンドを入力してDockerをインストールします。

$ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install -y docker-ce

 インストール後、rootユーザでなくても実行できるdockerコマンドを実行できるように以下のコマンドを実行します。

$ sudo usermod -aG docker $USER

 入力後、本体を再起動し、「docker version」などのコマンドでrootユーザでなくとも実行できることを確認してください。

Swapの設定をOFF

 kubenetesを使用する際にはSwap OFFにしないといけないため以下のコマンドでSwapの使用をOFFや再起動してもOFF状態が基本状態になるようにします。

$ sudo dphys-swapfile swapoff
$ sudo systemctl stop dphys-swapfile
$ sudo systemctl disable dphys-swapfile

IPフォワードを有効

 /etc/sysctl.confを編集し以下のコメントアウトされている以下の部分を有効にします。

net.ipv4.ip_forward=1

kubenetesのコマンドインストール

 最後に、kubenetesを構築するに必要なkubelet、kubectl、kukbeadmを以下のコマンドでインストールします。

$ curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg|sudo apt-key add -
$ echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kube.list
$ sudo apt-get update
$ sudo apt-get install kubelet kubeadm kubectl

 以上設定を行うことでkubenetesクラスタを構築するための事前準備は完了です。

kubernetesクラスタ構築

 kubernetesクラスタを作成するには以下の手順を行います。

  1. マスターノードの初期化
  2. コンテナネットワークブリッジflannel導入
  3. ワーカーの登録

マスターノードの初期化

 マスター機器にアクセスして作業を行います。

 以下コマンドを入力してマスターノードを初期化します。

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16

 上記コマンド実行後、発生するログ内で、「kubeadm join」と記載された以下のような文章をメモしてください。この部分はワーカーの登録で必要になります。

kubeadm join 192.168.0.24:6443 --token rkfwzo.9paicpp89gyvmdwn \
--discovery-token-ca-cert-hash sha256:58ff66d2d81e1c7b8b84d368d0ce44e768fe37be98583904875a34c2670b520b 

 rootユーザにならなくてもkubectlコマンドを実行できるように、以下のコマンドを入力します。

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

コンテナネットワークブリッジflannel導入

 以下のコマンドでコンテナネットワークブリッジのflannelを導入します。

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

 以上で、マスターの設定は完了です。

ワーカーの登録

 次に、ワーカーをマスターに登録します。なお、この作業については、ワーカー機器にアクセスして作業を行います。

 マスターノードを初期化された時のログでメモした部分を流用して以下のコマンドを実行します。

$ sudo kubeadm join 192.168.0.24:6443 --token rkfwzo.9paicpp89gyvmdwn \
--discovery-token-ca-cert-hash sha256:58ff66d2d81e1c7b8b84d368d0ce44e768fe37be98583904875a34c2670b520b 

 以上で、ワーカー機器の作業は終了です。実際にマスターに登録されたかの確認は、マスター機器にアクセスして、以下のコマンドを実行し確認します。

$ kubectl get node
NAME          STATUS     ROLES    AGE     VERSION
k8s-master    Ready      master   3m51s   v1.19.0
k8s-worker-1  NotReady   <none>   2s      v1.19.0          

Podの動作確認

 pod動作確認として、実際にnginxを動かして確認します。

 以下の作業はマスター機器にアクセスして作業をします。

nginxの登録

 nginx.ymlファイル名を作成して以下の文章を入力します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer

 以下のコマンドを実行してpodを起動します。

$ kubectl apply -f nginx.yml

 以下のコマンドでpodやserviceの状態を調べます。

$ kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
nginx-deployment-d46f5678b-k2dc7  1/1     Running   0          10s
$ kubectl get service
NAME          TYPE         CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes    ClusterIP    10.96.0.1      <none>        443/TCP        6m45s
nginx-service LoadBalancer 10.100.230.168 <pending>     80:30958/TCP   93s

 以下のコマンドでnginxアクセスできることを確認します。

$ curl 192.168.0.24:30958
$ curl 192.168.0.25:30958

 実際にcurlコマンドで確認した結果は以下の通りになります。

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
 <style> 
       body {
           width: 35em;
           margin: 0 auto;
           font-family: Tahoma, Verdana, Arial, sans-serif;
       }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
 working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

MetalLBを使用してコンテナにIP設定

 MetalLBを使用すればEXTARNAL-IPアドレスを対象のサービスに自動で割り振ることができます。

 以下のコマンドを実行してMetalLBを有効にします。

$ kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml

 metallb-config.ymlのファイルを作り以下の入力を行います。

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
      - name: default
        protocol: layer2
        addresses:
          - 192.168.0.200-192.168.0.220

 以下コマンドでを実行して、MetalLBの設定を読み込みます。

$ kubectl apply -f metallb-config.yml

 実行後、以下のコマンドを実行するとEXTERNAL-IPが<pending>から192.168.0.200に変更されていることがわかります。

$ kubectl get service
NAME          TYPE         CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes    ClusterIP    10.96.0.1      <none>        443/TCP        14m
nginx-service LoadBalancer 10.100.230.168 192.168.0.200 80:30958/TCP   9m44s

 EXTERNAL-IPに記載されたIPをcurlコマンドでアクセスしますと以下のように取得できます。

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
 <style> 
       body {
           width: 35em;
           margin: 0 auto;
           font-family: Tahoma, Verdana, Arial, sans-serif;
       }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
 working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Podの停止

 nginxのPodを停止する際には、以下のコマンドを入力して停止してください。

kubectl delete -f nginx.yml

ノード全ての初期化

 作成したクラスターを全て初期化する際に全ての機器で以下のコマンドを入力してください

sudo kubeadm reset

 初期化完了後、マスター機器で以下のコマンドを実行してください

rm -rf .kube