Kubernetesでの開発を楽にするskaffoldを使ってみる
Kubernetesを開発環境で使っていると、 コードを修正して確認する度に、imageを作り直し、Kubernetesへデプロイしなければならないため、開発効率がよくありません。 hostPathをマウントする方法で解決できますが、Kubernetesでは、マウントパスを絶対パスで記述しなければならないため、manifestを共有しチームで開発しようとすると、各々の環境に合わせてパスを設定し直さなければなりません。
上記のような問題を解決するツールである skaffold
というのを見つけたので試してみます。
どういったものか
- ファイルの変更を検知して、イメージのビルド・プッシュ・デプロイを自動で行ってくれる
- Google製(GoogleContainerTools)
- Kubernetesサーバ側に何か設定する必要はない
参考
- 公式ページ
- github
- マニュアル
検証環境
環境は以下です。
- PC: Ubuntu18.04
- Kubernetes環境: minikube(virtualbox)
- 管理コマンド: kubectl
- アプリケーション: 標準的なrailsアプリ
事前準備
skaffoldのインストール
以下の手順でインストールします。 https://skaffold.dev/docs/getting-started/
dockerの設定
minikubeのdockerを使います。
eval $(minikube docker-env)
設定する
skaffoldの設定ファイルである skaffold.yaml
を設定します。
skaffold init
というコマンドを実行すると、Kubernetesのmanifestを見て自動的に skaffold.yaml
を生成してくれます。
- skaffold.yaml
apiVersion: skaffold/v1beta9 kind: Config build: artifacts: - image: rails_app deploy: kubectl: manifests: - rails-deployment.yaml - rails-service.yaml
ちなみに、manifest
ファイルは以下のような感じです。
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: rails spec: replicas: 1 template: metadata: labels: role: app spec: containers: - args: - bash - -c - bundle exec rake db:migrate && bundle exec rails s -b # 検証用なので、いちいちdb:migrateしています。 0.0.0.0 image: rails_app imagePullPolicy: Never # minikube上にimageができるのでpullする必要ありません。 name: rails-app ports: - containerPort: 3000 volumeMounts: - mountPath: /usr/local/bundle name: bundle volumes: - hostPath: path: /tmp/bundle name: bundle
apiVersion: v1 kind: Service metadata: name: rails-app spec: ports: - name: "3000" port: 3000 targetPort: 3000 nodePort: 30080 selector: role: app type: NodePort
実行する
skaffold dev
で実行する
フォアグラウンドで待ち受けられます。
-v debug
で詳細に何をやっているのかが見られるので、気になる方はこちらのオプションをつけてみても良さそうです。
- ファイルの変更をする
適当にファイルを編集して保存すると、ビルド、デプロイが実行されました! (ブラウザで確認し、ちゃんと反映されていることも確認)
Generating tags... - rails_app -> rails_app:3ec4d44-dirty Tags generated in 26.202452ms Starting build... Found [minikube] context, using local docker daemon. Building [rails_app]... Sending build context to Docker daemon 40.27MB ・・・
podも新しくなっている様子
kubectl get pod NAME READY STATUS RESTARTS AGE rails-7b7c8bc85b-95ljp 1/1 Running 0 21s
この方法であれば、ビルド・デプロイの手間が省けるので、不自由なく開発ができそうです!
どういう仕組みなのか?
どうやら、Dockerfileの COPY(もしかしたらADDも)
の内容からどのファイルをウォッチするかを判断しているようで、
DockerfileまたはCOPYしている範囲に変更があれば、ビルド->タグ付け->デプロイを自動で行ってくれるようです。
注意点
注意点としては、Dockerfileのキャッシュを上手く利用する書き方をしていないと、ビルドする度に時間がかかってしまいます。 ソースをコピーする記述はなるべく下のほうに書いておくと良さそうです。 また、DockerfileのCOPYは、ディレクトリをさかのぼる記述は書けないので、ウォッチしたいファイルがちゃんとCOPYできるようファイル構成を考える必要があります。
以上、今日のところはこんな感じです。