MinikubeとTelepresenceで構築するKubernetesローカル開発環境

by

@wapa5pow

ogp1

1年半くらいKubernetesにアプリケーションをデプロイして本番・ステージングと動かしていますが、ローカル開発環境はDocker Composeを使って開発しています。Docker Composeでの開発はそこそこ快適ではあったものの実際Kubernetes上で動いていないので、細かい環境が異なります。かといってMacでKubernetesを動かそうとするといちいちDockerイメージを作ってデプロイしてなければいけなくて面倒です。

今回、MinikubeTelepresenceを使ってKubernetes上なのに快適なローカルな開発環境を構築できました。MinikubeでKubernetesを動かし、TelepresenceでMac上で動いている「プロセスをあたかもKubernetes上で動いているかのように動かせます。ホットリロードもできるのでDockerイメージを作ってkubectlコマンドでデプロイしなくても即時コードが反映されます。

Kubernetesの実行環境としてMinikubeとDocker for Macどちらを選ぶか

現在、Mac上でKubernetesを動かし、そこにアプリケーションをデプロイして開発しようとすると、MinikubeかDocker for MacのKubernetesかという選択肢となります。MinikubeはVirtual Machineのホスト上にKubernetesを構築し、Docker for Macはその上でKubernetesが動きます。どちらかを選択するかという話ですが、今回実際に開発しているコードで動かしてみたところDocker for MacのKubernetesは動作がとまったり安定しなかったのと、Kubernetesのバージョンがv1.10.11と求めているバージョンより低かったのでMinikubeにしました。MinikubeはただしくVirtual Machineのサイズを設定すればそこそこ安定して使えました。

Telepresenceについて

Telepresenceはどのようにローカルで動いているプロセスをKubernetes上で動いているかのようにしているかというと以下のように、ローカル環境でTelepresenceのクライアントが動き、開発しているソースを実行したプロセスがTelepresenceのクライアントからKubernetesにあるTelepresenceのプロキシを通して通信します。ローカルでプロセスが動いているのでホットリロードもでき高速に開発できます。

telepresence
(A fast development cycle with Telepresenceより)

MinikubeとTelepresenceを使ってローカル開発環境を実現

それでは実際に環境を構築してみます。今回はFlaskで作られた簡単なPythonのプログラム(ソースコードはここにはないですがサンプルでもなんでも簡単なもので構いません)を実際に動かしKubernetes環境でもホットリロードで開発できることを確かめます。

Minikubeのインストールですが、Running Kubernetes Locally via Minikubeあたりをみながらインストールするといいかなと思います。

Minikubeがインストールできたら以下のようにスタートします。ディスクサイズとかメモリとかCPUとかは各自のマシンによると思いますので適度に設定してください。自分はこれくらいあれば困りませんでした。

minikube start --disk-size 40g --memory 8192 --cpus 6

次に、PythonのプログラムをデプロイするためのKubernetesの設定を以下のように作ります。以下の設定はgcr.io/xxx/server-minikubeにDockerイメージがありますが、ローカルにあっても構いません。適宜かえてください。ただし、Minikubeは権限を設定しないと、Dockerイメージのレジストリにあるイメージが取得できないので、GCRにある場合は、Private Container Registriesを参考にして、ローカルにある場合は、Use minikube's built-in docker daemonを参考にして設定してください。

title=server.yaml
apiVersion: v1
kind: Service
metadata:
  name: server
spec:
  ports:
  - name: http
    port: 5000
  selector:
    app: server
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: server
  template:
    metadata:
      labels:
        app: server
    spec:
      containers:
      - name: server
        image: gcr.io/xxx/server-minikube:latest
        imagePullPolicy: Always
        command: ["python", "manage.py", "runserver"]
        ports:
        - containerPort: 5000
        readinessProbe:
          httpGet:
            path: /health
            port: 5000
          initialDelaySeconds: 5
          timeoutSeconds: 1

別途上記のserverにアクセスするためのIngress用の設定も作っておきます。別途、MinikubeのIngressのaddonの追加も行っておいてください。

title=ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
spec:
  backend:
    serviceName: server
    servicePort: 5000

上記をkubectlコマンドでMinikubeにデプロイします。念の為コンテキストをMinikubeにしてから行っておきます。

kubectl config use-context minikube
kubectl apply -f server.yaml
kubectl apply -f ingress.yaml

kubectl get podコマンドなどで正しくデプロイされたか確認しておきます。その上で、正しく疎通できるか、minikube ipコマンドで確認したIPにブラウザからアクセスしてみます。今回は、192.168.99.100だったので、ヘルスチェックのパスの192.168.99.100/healthにアクセスして確認しました。

いよいよTelepresenceを使ってローカルで動かしているPythonのプログラムがホットリロードできるか確かめてみます。といっても驚くほど簡単です。Telepresenceをインストールしてから以下のように実行します。

telepresence --swap-deployment server --expose 5000 --run python manage.py runserver

これだけで、Kubernetes上にあるserverデプロイメントのPodが置き換わります。ソースコードを変えてもホットリロードされ、実際にソースコードが変わっています。

まとめ

Macのローカル開発環境としてMinikubeとTelepresenceを使って快適に開発できる環境の構築を試しました。本番のアプリがKubernetes上で動作している場合は、ローカルでDocker Composeを使うより、Minikubeを使ったほうがより本番のKubernetesの環境に近づけられます。その場合、従来だとDockerイメージをいちいちビルドしてデプロイしなければなりませんでしたが、Telepresenceを使うことによりホットリロードもできる快適な開発環境が構築できました。これで不満だったローカルでのKubernetes上での開発が快適になり嬉しいです。