0.アプリを公開したい
久しぶりに投稿します。今回はKubernetesでNodePort Serviceを利用してアプリを公開する方法を紹介していきます。
Kubernetesを使って試しに、気軽にアプリをデプロイしてみたい(お金はかけたくない。。。)!という方向けです。
今回使用した環境はIBM Cloudですが、どのCloudでも同様にデプロイできると思います。Kubernetes環境の無料枠が一ヶ月で、期限が切れても再び構築することはできます。
無料枠ではIngressなどを使うことはできませんが、Serviceリソースの一つであるNodePortを利用してアプリを公開することはできます。
Dockerコンテナの作成からKubernetes上へのデプロイまでを行なっているので、これらの一連の流れが掴めるようにはなってると思います。
前提
- IBM Cloud アカウントの取得
- IBM CloudのKubernetes上にクラスターを構築してあること
- DockerがインストールされていてDocker Hubのアカウントを持っている
- 公開してみたいアプリがあること(なんでもよし。今回作成するアプリに関しては以下の環境が必要)
- Node.js(node: v12.18.2, npm: 6.14.5)環境があること
- create-react-appコマンドを使えること
1.サンプルアプリのDockerコンテナの作成
今回はcreate-react-appで簡単に作成できるReactアプリをデプロイしてみようと思います。まずはコンテナ化して動作確認します。
1-1. Reactアプリ作成(create-react-appはインストールされている前提)
$ create-react-app my-react-app
$ cd my-react-app
1-2. Dockerfile作成
Dockerfileを以下のように作成し、my-react-appディレクトリ直下に配置します。
FROM node:12
COPY . /app
WORKDIR /app
RUN npm run build && \
npm install -g serve
CMD [ "serve" , "-s", "build" ]
今回のコンテナ作成の流れとしてはproduction用の静的ファイルを生成し,それを静的ファイルサーバーを用いて実行するものになっています。
静的ファイルサーバー実行時、デフォルトでは5000番ポートを受け付けます。
1-3. ビルドし、ローカルで動くことを確認する
$ docker build -t my-react-app:0.0.1 .
$ docker run -p 5000:5000 my-react-app:0.0.1
INFO: Accepting connections at http://localhost:5000
#localhost:5000でreactアプリが動いていることができたらexit
2.DockerHubにpushする
2-1. 'docker tag'で1で作成したイメージに自分のDocker Hubのアカウント名(レポジトリ名)を付与する
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: <DockerHubアカウント名>
Password:
Login Succeeded
$ docker tag my-react-app:0.0.1 <DockerHubアカウント名>/my-react-app:0.0.1
2-2. イメージをDocker Hubのレポジトリににpushする
my-react-app $ docker push <DockerHubアカウント名>/my-react-app:0.0.1
The push refers to repository [docker.io/bangdr2018/my-react-app]
24531b8429e8: Pushed
ea8d003551da: Pushed
9cee2cb2fb8e: Mounted from library/node
eb3f44bfde1e: Mounted from library/node
3b93aab45097: Mounted from library/node
174e334f3f46: Mounted from library/node
cbe6bbd0c86f: Mounted from library/node
ef5de533cb53: Mounted from library/node
a4c504f73441: Mounted from library/node
e8847c2734e1: Mounted from library/node
b323b70996e4: Mounted from library/node
0.0.1: digest: sha256:f032be9c6a2530de810d1a29b75777a01655e7a23b64a7aa39e81f5154a82640 size: 2638
2-3. イメージがpushできたことDocker Hubのコンソール上で確認(アカウント名は念のため切ってます)
3. Kubernetesへのデプロイ、アプリの公開
3-1. kubectlコマンドのコンテキストを確認する。
コンテキストが存在しなかったり、ローカルなど異なるコンテキストとなっていた場合は、kubectlコマンドをダウンロードする
// すでにIBM Cloudに構築したKubernetesからkubectlコマンドをダウンロードしていた場合コンテキストは次のようになる
$ kubectl config current-context
<クラスター名>/<クラスターID>
ダウンロードしていなかった場合はIBM Cloudコンソール上でクラスターのプロファイルを開き、「アクセス」の箇所に以下のようにkubectlコマンドのダウンロード方法が載っている(ibmcloudコマンドをすでに使用できる場合「CLIツールの一回かぎりのセットアップ」は不要)。
3-2. deployment.ymlの作成
以下のようにdeployment.ymlを作成。containerのimageに2でpushしたイメージを指定する
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-react-app-deployment
spec:
selector:
matchLabels:
app: my-react-app
template:
metadata:
labels:
app: my-react-app
spec:
containers:
- name: my-react-app
image: <DockerHubアカウント名>/my-react-app:0.0.1
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 5000
Podが生成、Runnningとなっていることを確認(Podの名前はデプロイメント名に付随する)
$ my-react-app $ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-react-app-deployment-c4f95c7cd-rx8xt 1/1 Running 0 8s
3-3. NodePortを利用したserviceを作成する
以下のようにservice.ymlを作成。selectorのラベル(app: my-react-app)とPodのラベル(app: my-react-app)を一致させる。
ポートの番号は30000-32767の間に指定する。
apiVersion: v1
kind: Service
metadata:
name: my-react-app-service
spec:
type: NodePort
selector:
app: my-react-app
ports:
- port: 5000
targetPort: 5000
nodePort: 30080
protocol: "TCP"
name: "http-port"
serviceが生成されていることを確認の確認(Podの名前はデプロイメント名に付随する)
my-react-app $ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-react-app-service NodePort 172.21.94.246 <none> 5000:30080/TCP 10s
3-4. Nodeに割り振られているExternal IPを確認する
NodePort Serviceはその名の通り、:<ポート>で受信したトラフィックをコンテナに送信するものなので、nodeのEXTERNAL-IPを確認する。
// -o wideオプションで表示可能
$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP(これ!) OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
10.144.194.234 Ready <none> 13d v1.17.11+IKS 10.144.194.234 159.122.xxx.xxx Ubuntu 16.04.7 LTS 4.4.0-187-generic containerd://1.3.4
3-5. 公開されたアプリをみてみる
さあ緊張の瞬間ですが:で公開されたアプリを見てみましょう。
公開できました!やりましたね!
おわりに
今回はアプリのコンテナ化からKubernetes上へのデプロイまでの一連の流れを紹介してみました。
結構簡単に、かつ柔軟にデプロイできると思いました。
ただKubernetesのメリットとしてはこんなものではないので自分自身も勉強しつつ有益だと思ったらどんどん投稿していこうと思います。
次はKubernetesで構築したアプリの環境変数周りのリソースについて説明してみようかなと思ってます。