年中アイス

いろいろつらつら

minikubeで自分の作ったimageを使う

前回minikubeの実行環境を作りました。公開されているnginxのimageを使いましたが、実際は自分でimageを作成し、それを実行させることがほとんどだと思います。minikubeはdockerを内包しているので、そこでdocker buildすればimageが登録され、使うことができます。

nginxに静的ページを追加したコンテナを作って試す

まず、minikubeのdockerを使うために以下を実行します。

eval $(minikube docker-env)

次にお試し用のpage.htmlとDockerfileを作ります。

# page.html
echo '<html>
  <head><title>this is page</title></head>
  <body>original page</body>
</html>' > page.html

# Dockerfile 
echo 'FROM nginx:1.11

COPY page.html /usr/share/nginx/html/page.html' > Dockerfile

ファイル構成としてはこんな形になります。

k8s/  ・・・名前はなんでもよくここにいる状態でeval $(minikube docker-env)
  |- Dockerfile
  +- page.html

imageを作ります。タグはlatestだと動かないので、適当にバージョンつけます。

docker build -t example/nginxpage:0.1.0 .

k8sで動かします。

# コンテナ起動
kubectl run nginxpage --image=example/nginxpage:0.1.0 --port=80

# Macからアクセスできるように
kubectl expose deploy nginxpage --name=nginxpage-nodeport --type="NodePort"

ブラウザで確認します。

minikube service nginxpage-nodeport

標準ブラウザが立ち上がり、nginxのwelcomeページが表示されるので、URL欄に/page.htmlを追加します。 そうすると、original pageと表示され、自分で作ったコンテナが利用できていることがわかります。

参考

ローカルでkubernetesを動かせるminikubeを試す

kubernetes(以降k8s)は、GKE(GoogleContainerEngine)を使うのが簡単らしいですが、とりあえずローカル実行できる環境が欲しくなったりします。

minikubeは、VirtualBoxなどの上にk8sの環境を構築してくれるツールです。今回はとりあえずMac上にk8s環境を作り、nginxを動かしてアクセスするところまでやってみます。

インストール

以下の2つのツールと関連するものをインストールします。

  • kubectl: k8sの操作を行うコマンド
  • minikube: ローカルにk8s環境を作るコマンド

kubectlのインストール

gcloudコマンドでインストール管理できるので、gcloudコマンドを入れます。

ダウンロードページから、MacOS用の、tar.gzをダウンロードし解凍し、install.shを実行します。

tar xzvf google-cloud-sdk-145.0.0-darwin-x86_64.tar.gz
google-cloud-sdk/install.sh

注意点として、Python2.7が必要です。Mac標準なら大丈夫で、何か入れてたら、頑張って2.7にしましょう。pyenv(今env系は何がデファクトなんだろうか)とか入れればできるのかな。

kubectlは、gcloud componentsコマンドでインストールできます。

gcloud components install kubectl

他にもGCP関連のツール群はこのgcloud componentsで入れられます。

minikubeのインストール

今回はVirtualBox上に作るので、先にダウンロードページからdmgを落としてきてインストールします。

次にminikubeです。リリースページにあるコマンドでインストールします。最後にsudo で移動させてるので管理者パスワードを聞かれます。*1

curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.18.0/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

k8s環境の構築

構築と書いてますが、以下コマンドで済みます。(が少し時間かかります)

minikube start

k8sのイメージを落としてきて、起動し、kubectlに登録してくれます。終わったら、kubectlで接続先のk8s環境を確認します。

kubectl config get-contexts

CURRENT   NAME       CLUSTER    AUTHINFO   NAMESPACE
*         minikube   minikube   minikube

他の環境がないととりあえずminikubeだけです。GKEとか使うとここが増えます。

nginxを動かしてアクセスする

以下コマンドでnginxコンテナを動かします。

kubectl run nginx --image=nginx:1.11 --port=80

--imageオプションでdockerのimage名とtagを指定します。--portでコンテナが公開しているポートを指定します。

k8s上でコンテナは動き出しますが、これだけだとまだMacからアクセスはできません。以下でにアクセスできるようにします。

kubectl expose deployment nginx --name=nginx-nodeport --port=80 --target-port=80 --type="NodePort"

kubectl expose deploymentの後のnginxは、kubectl runの後に指定した名前(今回はnginx)と同じです。

これでMacからアクセスできるようになるんですが、どのIPとポートなのかわかりません。これはminikubeが直接ブラウザで開いてくれるので、それを使います。

minikube service nginx-nodeport

minikube serviceの後に指定してあるnginx-nodeportは、手前のkubectl exposeで指定した--nameの値です。

これで標準ブラウザが立ち上がり、VirtualBox仮想マシンIPと自動で割り当てられたポートでページが開かれます。今回だとnginxのwelcomeページが表示されます。

URLだけ欲しい場合は--urlオプションをつけます。

minikube service nginx-nodeport --url

# portは自動的に割り当てられます
http://192.168.99.100:31430

なぜMacからk8sのコンテナにアクセスできるのか

とりあえずやるところだけ先に書きましたが、ネットワーク周りをもう少し。今回幾つか手順を踏んで、Macからk8sのコンテナにアクセスできるようになっています。この先の説明に出てくるIPやポートは、今回私が試したものなので、環境によって異なる場合があります。

まず、MacVirtualBox仮想マシン間は、専用のネットワークが構成されて、つながっています。これは192.168.99.0/24です。

k8sは自身のネットワークを構成します。10.0.0.0(サブネットマスクパッとわからず)で、k8sネットワークが作られています。このネットワークは、Macからは直接アクセスできません。

そこで、kubectl expose--type="NodePort"を使って、k8sネットワーク上のアクセス先と、ノード(VirtualBox仮想マシン)をつなげています。今回だとMac<->VirtualBoxネットワークとk8sネットワークをつなげるために、kubectl exposeしているという方が正確です。本来は冗長化した複数のコンテナのアクセス先をまとめるためにkubectl exposeを使います。

--type=“NodePort”によって、VirtualBox仮想マシン192.168.99.100:31430(ポートは自動的に割り当てられる)が、k8sネットワーク上の10.0.0.161:80(IPは自動的に割り当てられる)にフォワードされるようになっています。k8sの方はkubectl get serviceで確認できます。VirtualBoxの方は、前述のminikube service nginx-portnode --urlです。

kubectl get service

NAME             CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes       10.0.0.1     <none>        443/TCP        2d
nginx-nodeport   10.0.0.161   <nodes>       80:31430/TCP   27m

アクセスの流れは以下になります。

Mac(VirtualBox network) 192.168.99.1
↓
minikube仮想マシン(VirtualBox network) 192.168.99.100:31430
↓
nginx-nodeport (k8s network)10.0.0.161:80
↓
nginx container(k8s networkのどこかIPとポート)

後始末

起動したものを止める方法

kubectl get service
kubectl delete service nginx-nodeport
kubectl get service

kubectl get deployment
kubectl delete deployment nginx
kubectl get deployment

minikube stop

まとめ

とりあえずローカルで動かすことができました。*2 公開、運用することなどを考えると、GKEが良さそうではありますが、まずは試すという点ではminikubeでもいいのかなと思います。

参考など

*1:特に最後の/usr/local/bin/移動は必須ではないので、その部分を除いて、./minikubeや、別のディレクトリに置いてPATHを通しても良いです。

*2:と言ってもコンテナイメージはdockerから持ってくるので完全にローカルというわけでもないですが

リリースを自動化したら思ったより楽になった

※2020/02/22 追記 Goで作ったツールは以下のGoReleaser + GithubActionsを使う方法に置き換えました。

reiki4040.hatenablog.com

-- 追記ここまで

rnzooの0.5.0を開発していくにあたって、機能的な追加の他に、リリースの自動化を行いました。もともとビルド自体はbashスクリプトで自動化していて、dockerを使ったコンテナ上でのビルドとアーカイブファイルの作成を行っていました。

今回、devバージョンをちょこちょこ出しながら進めるために、リリースにかかる手間を減らしたくなったので、少し腰を据えて改善しました。おかげで0.5.0-devは6まで簡単に繰り返しリリースしていくことができました。

以前

実際のリリース(homebrewに反映させる)は、毎回以下をやっていました。

書くとあんまりたいしたことないですが、手作業満載で、頻繁にやらない分、あれどうしてたっけみたいな状態になっていました。

何をやったか

単純にスクリプト化しました。とりあえず動作確認できたら、tag作ってリリーススクリプト実行してリリースされるというところまで。詳細は以下プルリクを参照ください。 https://github.com/reiki4040/rnzoo/pull/20/files

hubコマンドを使って、リリースファイルをアップロード

調べてみたらhubコマンドでできるということで、インストールしてスクリプトに追加しました。

Pull Requestを自動で作成する

こっちに書いたように、関連するプルリクを自動で作成して、最後確認してマージするように。別にPullRequestにせず、masterにそのままpushでもいいんですが、応用が利きそうなので、あえてPullRequestを経由する形にしました。

未解決

テスト

今回homebrewのauditだけ入れていますが、この自動化に際して、hashが間違っていたり、対象ファイルが存在しない(url間違っていた)などを拾ってくれたので、テスト大事ですね。

CI/CDサービスとの連携

まだ自分でキックしないといけないので、自動で開始できるともっと楽になるはず。プルリク作ったら自動テスト実施とか、マージしたらリリースみたいな自然なフローをサポートしてくれる形にしたい。

まとめ

当たり前ですが、自動化すると手間とミスが減るので楽ですね。プロジェクトの最初で足回りちゃんと作るのが後で効いてくるんだなと実感しました。地味地味としたところの突っ掛かりがなくなると、集中しやすくなります。