13
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

IBM CloudAdvent Calendar 2018

Day 25

Knative を IKS上で 稼働させてアプリをデプロイしてみた結果

Last updated at Posted at 2018-12-31

Knative(ケイ・ネイティブ)は、IBM Cloud Kubernetesサービスの上で簡単に動作するので、セットアップして、サンプルアプリのコンテナビルドと、動作テストまでを実施して記録です。

Knativeとは

Knativeは、アプリケーション開発者にとっての最大の課題、「実行基盤の整備や運用に悩まされることなく、即にアプリケーション開発に集中したい」に対する一つのソリューションです。 つまり、サーバーレスのワークロードを、Kubernetesクラスタで実行できる様になります。しかも、Knativeは、HELMとISTIOをベースとして構築されるため、面倒なセットアップは最小ですみます。

Knativeの実行環境のセットアップ

設置アップ方法は、Knative Install on IBM Cloud Kubernetes Service (IKS)にあります。このページにあるボタンをクリックすると、自動的に環境をセットアップするようなのですが、Before you beginから順番に設置アップしました。

この中では、環境変数にセットして、コマンドを実行するので、筆者が使った環境変数を以下に列挙しておきます。

export CLUSTER_NAME=knative
export CLUSTER_REGION=jp-tok
export CLUSTER_ZONE=tok04
export CLUSTER_K8S_VERSION=1.11.5

コマンドの実行は、IBM Cloudにログインして、順番に実行します。

alias ic='ibmcloud'
ic login

CLUSTER_ZONEで既にVLANを使っていれば、VLANのリストを表示してVLAN番号を取得する。

ic sl vlan list -d $CLUSTER_ZONE

次のコマンドで、IKSのクラスタを作成する。vlan番号は、前述の結果で得たID番号で置き換えます。

ic cs cluster-create --name=$CLUSTER_NAME \
  --zone=$CLUSTER_ZONE \
  --kube-version=$CLUSTER_K8S_VERSION \
  --machine-type=b2c.4x16 \
  --workers=3 \
  --private-vlan 244**** \
  --public-vlan 244***

大体20分くらいで、クラスタが稼働するので、ISTIOをインストール

kubectl apply --filename https://github.com/knative/serving/releases/download/v0.2.2/istio.yaml

ISTIOが介入するネームスペースを設定して、ポッドの動作を確認する。

kubectl label namespace default istio-injection=enabled
kubectl get pods --namespace istio-system

ISTIOのポッドが全部立ち上がる、または、処理が完了したら、Knativeをインストールする。

kubectl apply --filename https://github.com/knative/serving/releases/download/v0.2.2/release.yaml

次は起動完了確認の結果です。

$ kubectl get pods --namespace knative-serving
NAME                          READY   STATUS    RESTARTS   AGE
activator-6677bbc9d6-7jmzg    2/2     Running   0          2m
activator-6677bbc9d6-tvz57    2/2     Running   0          2m
activator-6677bbc9d6-vlkmm    2/2     Running   0          2m
autoscaler-5d87cc6b75-brfq6   2/2     Running   0          2m
controller-f4c59f474-tdm8q    1/1     Running   0          2m
webhook-5d9cbd46f7-ldmmx      1/1     Running   0          2m

$ kubectl get pods --namespace knative-build
NAME                                READY   STATUS    RESTARTS   AGE
build-controller-79d6cc9d57-hg2t9   1/1     Running   0          2m
build-webhook-f97d479f9-m9bcz       1/1     Running   0          2m

以上で、Knative利用の準備完了です。 およそ 30分くらいという感じです。

Serverlessのアプリのコンテナビルド

サーバーレスのクライアントから呼び出すためのコンテナを開発します。と言っても、このアプリケーションは、PythonのFLASKフレームワークで開発したマイクロサービス相当のサンプルコードを利用します。

ディレクトリappを作成して、Pythonのアプリを作成します。

$ tree
.
├── app
│   ├── Dockerfile
│   └── app.py
└── service.yaml

app.pyのコードは、以下の通りで、curlなどで、ルート / をアクセスすると、Hello と 環境変数TARGETに設定された文字列を返すだけのシンプルなRESTサービスです。

app.py
import os

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    target = os.environ.get('TARGET', 'World')
    return 'Hello {}!\n'.format(target)

if __name__ == "__main__":
    app.run(debug=True,host='0.0.0.0',port=int(os.environ.get('PORT', 8080)))

次のコマンドのリストを順番に実行して、このアプリをコンテナにビルドして、Docker Hubに登録します。

docker build -t maho/helloworld-python .
docker login
docker push maho/helloworld-python

以上で、Serverlessのコンテナの準備は完了です。

次に進む前に、ここで利用したDockerfileは以下の通りです。環境変数が回りグドい感じがしますが、気にせず利用ください。

FROM python
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . .
RUN pip install Flask
ENV PORT 8080
EXPOSE $PORT
CMD ["python", "app.py"]

Knativeのサービス登録(アプリ機能の登録)

コンテナの準備ができたら、Knativeのサービスを登録していきます。このためのマニフェストは、以下の通りです。環境変数 TAGETに応答する文字列(Python Sample v1)をセットしておきます。

service.yaml
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: helloworld-python
  namespace: default
spec:
  runLatest:
    configuration:
      revisionTemplate:
        spec:
          container:
            image: maho/helloworld-python
            env:
              - name: TARGET
                value: "Python Sample v1"

マニフェストを適用することで、ロードバランサーと連携したサービスが生成されます。そして、アクセストラフィックは、ドメイン名 helloworld-python.default.example.com でルーティングされるようになります。

$ kubectl apply -f service.yaml
service.serving.knative.dev/helloworld-python created

$ kubectl get svc knative-ingressgateway --namespace istio-system
NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                                                                                                                   AGE
knative-ingressgateway   LoadBalancer   172.21.63.101   ***.***.68.123   80:32380/TCP,443:32390/TCP,31400:32400/TCP,15011:31145/TCP,8060:30283/TCP,853:32466/TCP,15030:31171/TCP,15031:32012/TCP   48m

$ kubectl get ksvc helloworld-python  --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain
NAME                DOMAIN
helloworld-python   helloworld-python.default.example.com

アクセステスト

簡単な動作検証で、ドメイン名をDNSへ登録している訳にはいかないので、ヘッダーにドメイン名を設定して、サービスのEXTERNAL-IPに目がけて、アクセステストを実施します。

$ export IP_ADDRESS=***.***.68.123
$ curl -H "Host: helloworld-python.default.example.com" http://{$IP_ADDRESS}
Hello Python Sample v1!

RESTサービスの応答として、「Hello Python Sample v1!」がきました。

ここでは、検証のためにcurlでじかに利用しましたが、実際のアプリケーションからKnativeのサーバーレスを機能を呼び出す場合には、ベタにURLを書かずに、ラップ関数を設けて、コーディングし易いようにすると思います。というか、するべきだと思います。

どこが Serverlessなんだろう?

これじゃ、サーバーレスとしての動作が良くわからないですよね。

次の実行結果で、curlのアクセスが実行されるまで、Pythonで書いたコンテナのポッドは、存在していません。そして、アクセスが来ると、そのFQDNに対応するポッド(コンテナ)が起動して、要求を処理します。そして、要求が5分間を経過しても、要求がなければ、Pythonのサンプルアプリのポッドは終了させられ、リソースを解放します。

つまり、Knativeは、機能(アプリ)を利用しない場合は、資源を解放して待機しており、機能(アプリ)への要求があると、対応する機能(アプリ)のポッド(コンテナ)を起動して処理を実行しまます。

## サービスのFQDN helloworld-python.default.example.com を呼び出され前
$ kubectl get pod 
No resources found.

## 呼び出され後
$ kubectl get pod 
NAME                                                  READY   STATUS    RESTARTS   AGE
helloworld-python-00001-deployment-669888748b-gzzkq   3/3     Running   0          8s

$ kubectl get pod 
NAME                                                  READY   STATUS    RESTARTS   AGE
helloworld-python-00001-deployment-669888748b-gzzkq   3/3     Running   0          56s
<省略>
$ kubectl get pod 
NAME                                                  READY   STATUS    RESTARTS   AGE
helloworld-python-00001-deployment-669888748b-gzzkq   3/3     Running   0          5m

## 5分越えると自動クリーンナップ
$ kubectl get pod 
No resources found.

オートスケールはしないのか?

IKSには、2018年12月末現在で、ノードレベルのオートスケールが実装されていません。2019年はじめには、リリースされると思います。(個人の意見です) そのため、現在は、Knativeのアプリケーションに負荷をかけても、ノードレベルではスケールしませんが、もう少しすれば、ポッド数=0から、最大ノード数設定値までスケールするようになると思います。

まとめ

IKSでも、Knativeは利用できました。セットアップはとても簡単でした。IKSのノードレベルのオートスケールの実装が待ち遠しいですね。しかし、スケールの必要がなければ、現在のIKSでもKnativeは十分使い始められそうです。

13
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?