0. 前提

  • kubernetes, Dockerに関する基礎知識

1. 動作環境

  • EC2(t3.xlarge) (※補足 t3.largeだとcpu不足で動作しませんでした。)
  • Ubuntu
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
  • kind version 0.11.1
  • knative-serving v0.29.0
  • kn-quickstart Version: v1.2.0
  • Docker 20.10.7
  • npm v6.14.4

2. 試してみる

2.1 kind, kubectlのインストール

  • kindのインストール

https://kind.sigs.k8s.io/docs/user/quick-start/ を参考にインストールする

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.11.1/kind-linux-amd64
chmod +x ./kind
mv ./kind /usr/local/bin/kind
sudo apt-get update && sudo apt-get install -y apt-transport-https gnupg2
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl

2.2 kn, kn-quickstartコマンドのインストール

wget https://github.com/knative/client/releases/download/knative-v1.2.0/kn-linux-amd64
chmod +x kn-linux-amd64
mv ./kn-linux-amd64 /usr/local/bin/kn
wget https://github.com/knative-sandbox/kn-plugin-quickstart/releases/download/knative-v1.2.0/kn-quickstart-linux-amd64
chmod +x kn-quickstart-linux-amd64
mv ./kn-quickstart-linux-amd64 /usr/local/bin/kn-quickstart

2.3 npm, nodejsのインストール

  • npmのインストール
sudo apt install npm
npm -v 
  • nodejsのインストール
sudo apt install nodejs
nodejs -v

2.4 knativeクラスタを立ち上げる

kn quickstart kind

kind get clusters

2.5 サンプルアプリケーションをデプロイする

https://github.com/knative/docs/tree/main/code-samples/serving/hello-world/helloworld-nodejs を参考にサンプルアプリをデプロイする nodejsプロジェクトを作成し、expressをインストールする

mkdir knative-service-sample
cd knative-service-sample
npm init -y
npm install express

index.jsを作成する。index.jsの中身は下のようになる。

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  console.log('Hello world received a request.');

  const target = process.env.TARGET || 'World';
  res.send(`Hello ${target}!\n`);
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
  console.log('Hello world listening on port', port);
});

package.jsonを編集する。内容を下記のように編集する

{
  "name": "knative-serving-helloworld",
  "version": "1.0.0",
  "description": "Simple hello world sample in Node",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "author": "",
  "license": "Apache-2.0",
  "dependencies": {
    "express": "^4.16.4"
  }
}

Dockerfileを作成する。下記のように記載する

# Use the official lightweight Node.js 12 image.
# https://hub.docker.com/_/node
FROM node:12-slim

# Create and change to the app directory.
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure both package.json AND package-lock.json are copied.
# Copying this separately prevents re-running npm install on every code change.
COPY package*.json ./

# Install production dependencies.
RUN npm install --only=production

# Copy local code to the container image.
COPY . ./

# Run the web service on container startup.
CMD [ "npm", "start" ]

.dockerigonerファイルを記載する

Dockerfile
README.md
node_modules
npm-debug.log

service.yamlを編集する usernameの部分は各自のDockerhubのユーザー名に変更する

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-nodejs
  namespace: default
spec:
  template:
    spec:
      containers:
        - image: docker.io/{username}/helloworld-nodejs
          env:
            - name: TARGET
              value: "Node.js Sample v1"

Dockerイメージをビルドする

docker build -t {username}/helloworld-nodejs .

docker push {username}/helloworld-nodejs

k8sクラスタにデプロイする

kubectl apply --filename service.yaml

サービスのエンドポイントを確認する

kubectl get ksvc helloworld-nodejs  --output=custom-columns=NAME:.metadata.name,URL:.status.url

アプリにアクセスしてみる。

curl http://helloworld-nodejs.default.1.2.3.4.sslip.io

無事にデプロイできると最初はSTATUSがRunningだが途中からTerminatingになることが分かる。 別のターミナルでkubectl get po -wしながら、curl http://helloworld-nodejs.default.1.2.3.4.sslip.io してみると再度Podが立ち上がる。

3. クラスタを片付ける

Knativeはかなりリソースを消費するので、今後使用しない場合はクラスタを削除しましょう。

kind delete clusters knative

4.最後に

今回はknativeでサーバレスを試してみました。knative以外にも、kubernetesではKEDAでサーバレスを実現できるようです。 こちらも記事( KEDA v2をkindで動かしてみる )にしているので時間がある時に読んでみて下さい。

5. 参考にした記事