Tamanyan.me | たまにゃんのエンジニアブログ

10分でローカルのKubernetesクラスタにNode.jsで構築したWeb Appをデプロイする。

この記事で分かる事

  • Node.js Web AppをKubernetesクラスタ上に構築する方法
  • Docker for Mac Kubernetesの使い方
  • Kubernetes Dashboardのインストール方法

今回使ったサンプルは tamanyan/k8s-node-sample にある。

Kubernetes を知る

Dockerは触っていてもKubernetesは初めてという人は結構多いのではないだろうか?

「Kubernetesは、コンテナ化したアプリケーションのデプロイ、スケーリング、および管理を行うための、オープンソースのコンテナオーケストレーションシステムである」

と書かれていても全くピンと来ない。まずオーケストレーションってなんだよ、曲でも作るのか?と冗談のように考える人もいるだろう。

オーケストレーション (コンピュータ)

オーケストレーション(英: Orchestration)は、複雑なコンピュータシステム/ミドルウェア/サービスの配備/設定/管理の自動化を指す用語。

Pod, Service, Nodeなど一般用語にもあるような独自の概念が出てきてイマイチとっつきにくいKubernetesを理解するために、 まず以下の Video を見て雰囲気を感じてもらいたい。 英語だが、字幕をつけて絵だけ見ていても雰囲気を感じ取れると思う。

Docker for Mac をインストール

Docker Community Edition for Mac に行き、以下の Get Docker CE for Mac (Stable) からダウンロードする。

Docker for Mac のインストール

Kubernetes を有効にする

Docker アプリからPreferencesを開き、Applyを押して有効にする。

Docker for Mac の設定

使用するClusterをdocker-for-desktopに変更する。

$ kubectl config use-context docker-for-desktop

Kubernetes Dashboard をインストール

Kubernetes Clusterの状態確認するためにWeb UI kubernetes/dashboardをインストールする。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
echo "apiVersion: rbac.authorization.k8s.io/v1beta1                                                                                                                                                       
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
  labels:
    k8s-app: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system" | kubectl apply -f -
$ kubectl proxy

以下のURLにアクセスする

http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/

Kubernetes Dashboard

Node.js Web AppをKubernetesクラスタにデプロイ

ようやく準備が完了したので、以下のアーキテクチャを構築を目標にする。今回はServiceDeploymentのみを使用する。

Kunerbetes アーキテクチャ

1. サンプルプロジェクトをClone

サンプルプロジェクトをGithubからCloneする

$ git clone https://github.com/tamanyan/k8s-node-sample.git

プロジェクトのディレクトリ構成

$ tree -L 2 -I 'node_modules' .
.
├── Makefile # command list
├── README.md
├── k8s
│   ├── deployment.yaml # Kubernetes Deployment
│   └── service.yaml # Kubernetes Service
└── node-app
    ├── Dockerfile # Dockerfile for Node.js app
    ├── index.js
    ├── package-lock.json
    └── package.json

Dockerfile

FROM node:8.12.0-alpine

ENV NODE_ENV=development

ARG project_dir=/app/

WORKDIR /app/

ADD index.js $project_dir
ADD package.json $project_dir
ADD package-lock.json $project_dir

RUN npm install

EXPOSE 3000

CMD ["npm", "start"]

index.js

const express = require('express')
const app = express()
const port = process.env.PORT || 3000

app.get('/', (req, res) => {
  res.json({
    message: 'Hello Sample Node.js app',
    localAddress: req.connection.localAddress,
  });
})

app.listen(port, () => console.log(`Sample app listening on port ${port}!`))

2. Node AppのDocker Imageをビルド

$ make build
docker build --no-cache -t gcr.io/myproject/node-app:v1 node-app

3. Node Appのデプロイ

$ make deploy
kubectl apply -f k8s/deployment.yaml
deployment.apps/sample-node-app configured
kubectl apply -f k8s/service.yaml
service/sample-node-app-service configured

4. Node.js Web Appのデプロイ

http://localhost にアクセス

Node.js サンプルアプリ

5. Node.js Web Appの削除

$ make clean
kubectl delete -f k8s/deployment.yaml
deployment.apps "sample-node-app" deleted
kubectl delete -f k8s/service.yaml
service "sample-node-app-service" deleted

Kubernetesのマニフェストファイルの中身

deployment.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: sample-node-app
  labels:
    app: sample-node-app
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: sample-node-app
    spec:
      containers:
      - name: sample-node-app
        image: gcr.io/myproject/node-app:v1
        command:
        ports:
          - containerPort: 3000

service.yaml

kind: Service
apiVersion: v1
metadata:
  name: sample-node-app-service
spec:
  type: LoadBalancer
  selector:
    app: sample-node-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000

まとめ

今回はほぼ最小の構成でNode.js Web AppをKubernetesクラスタにデプロイした。DeploymentServiceはKubernetes上に構築したアプリを公開するのに最も基礎的な事である。

参考URL


たまにゃん🇹🇭バンコクの機械学習エンジニア
バンコク(タイ)のソフトウェアエンジニア。元日本経済新聞社のiOSエンジニア。2018年からタイの自動車系の会社に転職。デジタルマーケティング、フロントエンド、データ基盤構築、機械学習辺りが最近の仕事。2019年からKaggleを始める。Kaggleソロ銀🥈1個。データサイエンス・ソフトウェアエンジニアリング・バンコクの事のついて情報発信する。