Cloud Penguins

Flying penguins in the cloud.

最強のServerlessプラットフォーム? Knativeを動かしてみるぞい

ということで前回の記事に引き続き、発表されたばかりのKnativeを動かしてみました。

jaco.udcp.info

GKE環境を用意する

Knativeを動かすにはk8s環境が必要ですので、今回はGKEに環境を用意します。なおk8s本体とKubectlは1.10以上が必要です。

KnativeはIstioなども含むリッチな仕組みのため、それなりのリソースを要求します。なのでやや大きめのインスタンスで立ち上げていますが、節約したい方はmachine-typeやnodeの数を編集してください。

export CLUSTER_NAME=knative
export CLUSTER_ZONE=asia-northeast1-a

gcloud container clusters create $CLUSTER_NAME \
  --zone=$CLUSTER_ZONE \
  --cluster-version=latest \
  --machine-type=n1-standard-4 \
  --enable-autoscaling --min-nodes=1 --max-nodes=5 \
  --enable-autorepair \
  --scopes=service-control,service-management,compute-rw,storage-ro,cloud-platform,logging-write,monitoring-write,pubsub,datastore \
  --num-nodes=3

k8s立ち上がったらget-credentials

gcloud container clusters get-credentials knative

カレントユーザーにcluster-adminをつけます。

kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value core/account)

kubectlを使って、Istioをセットアップします

kubectl apply -f https://storage.googleapis.com/knative-releases/serving/latest/istio.yaml

defaultネームスペースにラベル設定

kubectl label namespace default istio-injection=enabled

Istioの諸々がRunningになっているか確認

kubectl get pods -n istio-system

NAME                                       READY     STATUS    RESTARTS   AGE
istio-citadel-7bdc7775c7-lktlt             1/1       Running   0          59s
istio-egressgateway-795fc9b47-tcp76        1/1       Running   0          1m
istio-ingress-84659cf44c-2gmlw             1/1       Running   0          1m
istio-ingressgateway-7d89dbf85f-qjpg5      1/1       Running   0          1m
istio-pilot-66f4dd866c-lr7zw               1/2       Running   0          1m
istio-policy-76c8896799-74m52              2/2       Running   0          1m
istio-sidecar-injector-645c89bc64-gz5vb    1/1       Running   0          59s
istio-statsd-prom-bridge-949999c4c-p97lv   1/1       Running   0          1m
istio-telemetry-6554768879-pmkqq           2/2       Running   0          1m

Knativeコンポーネントをセットアップ

Knative Servingをセットアップします

kubectl apply -f https://storage.googleapis.com/knative-releases/serving/latest/release.yaml

Runningになっているか確認してみましょう

kubectl get pods -n knative-serving

NAME                          READY     STATUS    RESTARTS   AGE
activator-6bb6f6755f-l4ks8    2/2       Running   0          30s
controller-79cbd84cfb-n6l6h   1/1       Running   0          29s
webhook-7c884f4554-h7tx5      1/1       Running   0          29s

なんとこれだけでKnativeのセットアップは終わりです。それでは、実際に何かデプロイしてみましょうか。

サンプルアプリのデプロイ

service.yamlを作成し、以下の内容を記述してください。

apiVersion: serving.knative.dev/v1alpha1 # Current version of Knative
kind: Service
metadata:
  name: helloworld-go # The name of the app
  namespace: default # The namespace the app will use
spec:
  runLatest:
    configuration:
      revisionTemplate:
        spec:
          container:
            image: gcr.io/knative-samples/helloworld-go # The URL to the image of the app
            env:
            - name: TARGET # The environment variable printed out by the sample app
              value: "Go Sample v1"

このサンプルアプリは、環境変数 TARGETの中身を表示するアプリケーションです。このyamlの例の場合、 "Go Sample v1" という文字を表示します。

保存した後、kubectl applyします

kubectl apply -f service.yaml

> service "helloworld-go" created

作成されたリソースをみてみます

kubectl get all

NAME                                    AGE
deploy/helloworld-go-00001-deployment   10s

NAME                                          AGE
rs/helloworld-go-00001-deployment-d47886fcb   10s

NAME                   AGE
routes/helloworld-go   10s

NAME                AGE
svc/helloworld-go   10s

NAME                           AGE
configurations/helloworld-go   10s

NAME                            AGE
revisions/helloworld-go-00001   10s

NAME                                                READY     STATUS    RESTARTS   AGE
po/helloworld-go-00001-deployment-d47886fcb-c97kx   3/3       Running   0          10s

NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
svc/helloworld-go                 ClusterIP   10.63.246.221   <none>        80/TCP         10s
svc/helloworld-go-00001-service   NodePort    10.63.252.252   <none>        80:30048/TCP   10s
svc/kubernetes                    ClusterIP   10.63.240.1     <none>        443/TCP        12h

なんかsvc/helloworld-go以外にもいっぱい作られてますね!

作成したアプリへのアクセス

istio-system namespaceを見てみると、knative-ingressgatewayというものが作られていることが分かります。

このknative-ingressgatewayが、アプリケーションへのルーティングを担うコンポーネントになります。

kubectl get svc knative-ingressgateway -n istio-system

NAME                     TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)                                      AGE
knative-ingressgateway   LoadBalancer   10.23.247.74   35.203.155.229   80:32380/TCP,443:32390/TCP,32400:32400/TCP   2d

以下のコマンドでknative-ingressgatewayのEXTERNAL-IPを取得しておきます

export IP_ADDRESS=$(kubectl get svc knative-ingressgateway -n istio-system -o 'jsonpath={.status.loadBalancer.ingress[].ip}')

次に、以下のコマンドで、services.serving.knative.devを取得します

kubectl get services.serving.knative.dev helloworld-go  -o=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain

NAME            DOMAIN
helloworld-go   helloworld-go.default.example.com

DOMAINというところに、今回のアプリ向けのドメインが記されています。 knative-ingressgatewayはリクエストを見て、このドメインへのアクセスであれば作成されたアプリケーションへのルーティングを行うという動きをします。

とはいえexample.comは例示用ドメインなので、今回はcurlでホストヘッダを指定することで動きを見てみます。

curl -H "Host: helloworld-go.default.example.com" http://${IP_ADDRESS}

Hello World: Go Sample v1!

ほら、期待した文字列が表示されていますよね?

まとめ

ということで、Knativeは簡単にセットアップできるよという話を紹介されていただきました。

ただ、ぶっちゃけ今回のサンプルアプリでは、Knativeの何がいいのか分からないですよね? うん、僕も分かりません。

そもそもServerlessって言ってたのにどこにもServerless要素ないやん、こんなん素のKubernetesと変わらんやん! ってツッコみたくなるかと思いますが、徐々に解説していきますのでもう少しお待ちください。

Knativeはさまざまな方法で利用が出来るプラットフォームです。なので、1記事ではとてもとても紹介しきれないのです。

今回は、KnativeはServerless Platformでありながらも、従来のようなアプリケーションも動かすことができる という点を理解して頂ければよいかなと思います。

次回は、Buildpackを利用したアプリケーションのデプロイについて解説する予定です。

(参考)お片付け

k8sをお片付けするには以下のコマンドで削除します

gcloud container clusters delete $CLUSTER_NAME --zone $CLUSTER_ZONE