ローカル開発環境として minikube + kompose を使ってみる

  • 巷ではk8sが流行っているが、そもそもどんなことができるか理解できていないので、どういったものか触ってみたい
  • 業務ではdockerを使った開発環境の導入を行っているが、複数にまたがったロールの管理がしにくいので解決したい。こういったことはk8sなら解決できるのでは?と、ふと思った。

ということから、まずは、ローカル環境でk8s環境を構築することができる minikube を使って、ローカル環境を構築してみることにしました。

今回は練習として、以前、自分で作成したrailsのアプリケーションをデプロイし動かせるようにするところまで行います。 (普通のrailsアプリケーションなので、特別な設定は必要ありません。)

デプロイする予定のアプリケーションの開発環境は、すでにdocker環境(docker-compose環境)で動くようになっています。 せっかくなので、docker-compose.ymlをk8sの設定ファイルに変換してくれる kompose というツールを使ってみようと思います。

minikubeとは?

macOSLinux、およびWindowsvirtualboxなどのVM上にKubernetesクラスタを構築できるものです。

公式サイト:

github.com

  • こちらの手順でインストールできます。

Install Minikube - Kubernetes

komposeとは?

docker-compose.yml をk8s用の設定ファイルに変換してくれるツールです。

公式サイト

Kubernetes + Compose = Kompose

(インストール方法もこちらにあります。)

まずは、チュートリアルをやってみる

そもそも、k8sの使い方がわからなかったので、以下のチュートリアルで学習しました。

Hello Minikube - Kubernetes

開発環境を作っていく

以下の記事を参考にしました。

Docker ComposeからMinikube + Komposeに移行してみよう - Qiita

hawksnowlog: kompose を使って kubernetes 上で docker-compose してみる

基本的な流れは上記の記事の通りですが、自分なりにハマった点などを次にまとめました。

クラスターを作成する

  • minikube start でminikubeを起動
    • 実行すると仮想マシンが作成されます。
    • --vm-driver で、ドライバーの種類を設定できますが、デフォルトはvirtualboxが指定されるので、virtualboxを使う人はそのままで良いです。

komposeでk8sのファイルに変換する

  • アプリケーションのディレクトリ配下で kompose convert --volumes hostPath を実行します。

すると、以下2種類のファイルが作成されました。

kompose convert --volumes hostPath
INFO Kubernetes file "rails-service.yaml" created
INFO Kubernetes file "rails-deployment.yaml" created

ちなみに、元々の構成はこうでした。 必要なものを Dockerfile でインストールして、ソースコードや設定は docker-compose.yml に書くようにしています。

  • Dockerfile
FROM ruby:2.6.1

ENV LANG=C.UTF-8 TZ=Asia/Tokyo

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir -p /usr/src/app
RUN gem install bundler
WORKDIR /usr/src/app
  • docker-compose.yml
version: '3'

services:
  rails:
    build: ./
    command: bash -c 'bundle install && bundle exec rake db:migrate && bundle exec rails s -b 0.0.0.0'
    volumes:
      - .:/usr/src/app
      - bundle:/usr/local/bundle
    ports:
      - '3000:3000'

volumes:
  bundle:

kompose でデプロイする

続いて、kompose up --volumes hostPath で、minikube にデプロイしていこうと思ったのですが、以下のエラーが発生してしまいました。

FATA Error while deploying application: k.Transform failed: image key required within build parameters in order to build and push service 'rails'

どうやら、Dockerfile の指定はできないので、一度イメージ化しDockerレジストリに登録してあげる必要があるようです。 (k8s上で使うには、環境のイメージをどこかのレジストリにpushし、そこからpullするように設定する必要があるっぽいです。)

Dockerレジストリをローカルにたて、build: ./image: localhost:5000/takapi/app_rails:v1 にし再コンバート・再デプロイ。

minikubeのdocker側にimageを作ることで、ローカルでDockerレジストリを立てる必要はありませんでした。 単純に image: にイメージの名前を指定すればOKです。

詳しくはこちらの記事をご参照ください。 minikubeでローカルのdocker imageを使う - Qiita

今度は、デプロイできたようです。

kompose up --volumes hostPath
INFO We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead.

INFO Deploying application in "default" namespace
INFO Successfully created Service: rails
INFO Successfully created Deployment: rails

Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.

しかし、おや?ステータスが CrashLoopBackOff になっているようです。

kubectl get pods
NAME                     READY   STATUS             RESTARTS   AGE
rails-6747b44c87-r2tf5   0/1     CrashLoopBackOff   4          2m19s

logを見てみる

kubectl logs rails-6747b44c87-r2tf5
Could not locate Gemfile

おそらく、ファイルがマウントされていないのでしょう。 しかし、ホストからコンテナにファイルをマウントする方法がわからなかったので、今回は泣く泣くイメージにソースコードを突っ込むようにして対応します 😭

再デプロイする

コードをイメージに含めるようにし、再度デプロイ。 これで正常にデプロイ出来ました。

kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
rails-756f6f594b-mwzc5   1/1     Running   0          25m

kubectl logs rails-756f6f594b-mwzc5
INFO  WEBrick 1.4.2
INFO  ruby 2.6.1 (2019-01-30) [x86_64-linux]
INFO  WEBrick::HTTPServer#start: pid=1 port=3000
  • Dockerfile
FROM ruby:2.6.1

ENV LANG=C.UTF-8 TZ=Asia/Tokyo

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir -p /usr/src/app
RUN gem install bundler
WORKDIR /usr/src/app

COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . ./
  • docker-compose.yml
version: '3'

services:
  rails:
    image: localhost:5000/takapi/app_rails:v1
    command: bash -c 'bundle exec rake db:migrate && bundle exec rails s -b 0.0.0.0'
    ports:
      - '3000:3000'

外部から接続できるようにする

アプリケーションを外部から接続できるようにします。

kubectl delete service rails
kubectl expose deployment rails --type=NodePort

これで外部からアプリケーションのURLを叩けるようになりました。

アプリケーションを開く

以下のコマンドを叩くことによって、ブラウザが立ち上がり自動的にアプリケーションのページを開いてくれます。

minikube service rails

まとめ

この手順で、アプリケーションをデプロイすることができました。

まだ手探り状態なので、minikubeの機能かなにかでローカルファイルのマウントの方法があるのか、それとも仕組みとしてできないものなのかはまだわかっていないのですが、 仮にそもそもローカルのファイルがマウントできないのであれば、ちょっとの修正でもイメージ化->デプロイをしなければ確認ができなので、開発環境としては、ちょっと辛くなりそうだなぁという気持ちです。

調べてみたところ、良い感じに自動でやってくれる Skaffold というものがあったので、今度試してみたいと思います。 あとはこのへんなど

www.telepresence.io

以上、今日のところはこんな感じです。