MinikubeとTelepresenceで構築するKubernetesローカル開発環境
1年半くらいKubernetesにアプリケーションをデプロイして本番・ステージングと動かしていますが、ローカル開発環境はDocker Composeを使って開発しています。Docker Composeでの開発はそこそこ快適ではあったものの実際Kubernetes上で動いていないので、細かい環境が異なります。かといってMacでKubernetesを動かそうとするといちいちDockerイメージを作ってデプロイしてなければいけなくて面倒です。
今回、MinikubeとTelepresenceを使って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のプロキシを通して通信します。ローカルでプロセスが動いているのでホットリロードもでき高速に開発できます。
(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を参考にして設定してください。
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の追加も行っておいてください。
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上での開発が快適になり嬉しいです。