Eventing
Eventing は消費及び生産に使うイベント・ビルディング・ブロックを提供し、 CloudEvents の仕様に従って実現します。このコンポーネントの目標はイベントの抽象化であり、開発者はバックエンドの具体的な詳細に注意を払う必要がなく、どのメッセージ・キューを使うかに迷うこともありません。
hannels
apiVersion: channels.knative.dev/v1alpha1
kind: Bus
metadata:
name: kafka
spec:
dispatcher:
args:
- -logtostderr
- -stderrthreshold
- INFO
env:
- name: KAFKA_BROKERS
valueFrom:
configMapKeyRef:
key: KAFKA_BROKERS
name: kafka-bus-config
image: gcr.io/knative-releases/github.com/knative/eventing/pkg/buses/kafka/dispatcher@sha256:d925663bb965001287b042c8d3ebdf8b4d3f0e7aa2a9e1528ed39dc78978bcdb
name: dispatcher
apiVersion: feeds.knative.dev/v1alpha1
kind: EventSource
metadata:
name: github
namespace: default
spec:
image: gcr.io/knative-releases/github.com/knative/eventing/pkg/sources/github@sha256:a5f6733797d934cd4ba83cf529f02ee83e42fa06fd0e7a9d868dd684056f5db0
source: github
type: github
apiVersion: feeds.knative.dev/v1alpha1
kind: EventType
metadata:
name: pullrequest
namespace: default
spec:
description: notifications on pullrequests
eventSource: github
apiVersion: flows.knative.dev/v1alpha1
kind: Flow
metadata:
name: k8s-event-flow
namespace: default
spec:
serviceAccountName: feed-sa
trigger:
eventType: dev.knative.k8s.event
resource: k8sevents/dev.knative.k8s.event
service: k8sevents
parameters:
namespace: default
action:
target:
kind: Route
apiVersion: serving.knative.dev/v1alpha1
name: read-k8s-events
以上は簡単な紹介であり、続いてはMinikubeを通じてKnativeの機能に少しずつなじみましょう。
準備作業
Minukubeを起動
まずはMinikubeを通じて仮想マシンを起動し、単一ノードのKubernetesをデプロイします。ここでは多くのシステム・サービスを使用するので、より多くのシステム・リソースが必要です:
$ minikube start --memory=8192 --cpus=4 \
--kubernetes-version=v1.10.5 \
--extra-config=apiserver.admission-control="LimitRanger,NamespaceExists,NamespaceLifecycle,ResourceQuota,ServiceAccount,DefaultStorageClass,MutatingAdmissionWebhook"
完了したら、kubectlで確認します:
$ kubectl get no
NAME STATUS ROLES AGE VERSION
minikube Ready master 1m v1.10.5
Knativeをデプロイ
KnativeはIstioに基づいて開発されたので、まずは関連サービスをデプロイする必要があり、ここではkubectlによって作成します:
$ curl -L https://storage.googleapis.com/knative-releases/serving/latest/istio.yaml \
| sed 's/LoadBalancer/NodePort/' \
| kubectl apply -f -
# 設定 inject namespace
$ kubectl label namespace default istio-injection=enabled
イメージ・ファイルのダウンロードとIstioサービスの起動は少し時間がかかりますが、完了後は次のようになります:
$ kubectl -n istio-system get po
NAME READY STATUS RESTARTS AGE
istio-citadel-7bdc7775c7-jn2bw 1/1 Running 0 5m
istio-cleanup-old-ca-msvkn 0/1 Completed 0 5m
istio-egressgateway-795fc9b47-4nz7j 1/1 Running 0 6m
istio-ingress-84659cf44c-pvqd5 1/1 Running 0 6m
istio-ingressgateway-7d89dbf85f-tgm24 1/1 Running 0 6m
istio-mixer-post-install-lvrjv 0/1 Completed 0 6m
istio-pilot-66f4dd866c-zmbv5 2/2 Running 0 6m
istio-policy-76c8896799-cqmdn 2/2 Running 0 6m
istio-sidecar-injector-645c89bc64-9mdwx 1/1 Running 0 5m
istio-statsd-prom-bridge-949999c4c-qhdgf 1/1 Running 0 6m
istio-telemetry-6554768879-b6vss 2/2 Running 0 6m
続いてはKnativeコンポーネントをKubernetesクラスターにデプロイします。オフィシャル・サイトではrelease-lite.yamlファイルを提供して軽量化されたテスト環境の作成をサポートするので、直接kubectlを通じて作成できます:
$ curl -L https://storage.googleapis.com/knative-releases/serving/latest/release-lite.yaml \
| sed 's/LoadBalancer/NodePort/' \
| kubectl apply -f -
イメージ・ファイルのダウンロードと関連サービスの起動は少し時間がかかりますが、完了後は次のようになります:
# Monitoring
$ kubectl -n monitoring get po
NAME READY STATUS RESTARTS AGE
grafana-798cf569ff-m8w9c 1/1 Running 0 4m
kube-state-metrics-77597b45f8-mxhxv 4/4 Running 0 1m
node-exporter-8wbxd 2/2 Running 0 4m
prometheus-system-0 1/1 Running 0 4m
prometheus-system-1 1/1 Running 0 4m
# Knative build
$ kubectl -n knative-build get po
NAME READY STATUS RESTARTS AGE
build-controller-5cb4f5cb67-bs94k 1/1 Running 0 6m
build-webhook-6b4c65546b-fzffg 1/1 Running 0 6m
# Knative serving
$ kubectl -n knative-serving get po
NAME READY STATUS RESTARTS AGE
activator-869d7d76c5-fngdm 2/2 Running 0 7m
autoscaler-65855c89f6-pmzhr 2/2 Running 0 7m
controller-5fbcf79dfb-q8cb8 1/1 Running 0 7m
webhook-c98c7c654-lpnjj 1/1 Running 0 7m
ここまでには既にKnativeコンポーネントのデプロイが完了し、次はいくつかの例で Knativeの機能について理解を深めます。
Knativeアプリケーションをデプロイ
上のコンポーネントをデプロイした後、Knativeのアプリケーションとファンクションを作成することができます。ここでは簡単なHTTPサーバーとSlackでChannelメッセージングを実装し、その中ではBuild、BuildTemplateとKnative Serviceなどのリソースを使います。始める前に、まずGitを通じてサンプル・プロジェクトを取得し、ここでは主にその中のKubernetesデプロイ・ファイルを使います:
$ git clone https://github.com/kairen/knative-slack-app
$ cd knative-slack-app
この例ではKanikoを利用してアプリケーションのコンテナ・イメージ・ファイルを構築し、出来上がったイメージ・ファイルを自動的にDockeHubにアップロードするので、自分のDockerHubにアップロードできるように、Secertとサービス・アカウントを作成してDocker IDとパスワードをKnative servingに使わせます:
$ export DOCKER_ID=$(echo -n "username" | base64)
$ export DOCKER_PWD=$(echo -n "password" | base64)
$ cat deploy/docker-secret.yml | \
sed "s/BASE64_ENCODED_USERNAME/${DOCKER_ID}/" | \
sed "s/BASE64_ENCODED_PASSWORD/${DOCKER_PWD}/" | \
kubectl apply -f -
$ kubectl apply -f deploy/kaniko-sa.yml
Slackの情報を保存し、Slack Appに使わせるためにSecretを作成します。(例えばToken):
$ export SLACK_TOKEN=$(echo -n "slack-token" | base64)
$ export SLACK_CHANNEL_ID=$(echo -n "slack-channel-id" | base64)
$ cat deploy/slack-secret.yml | \
sed "s/BASE64_ENCODED_SLACK_TOKEN/${SLACK_TOKEN}/" | \
sed "s/BASE64_ENCODED_SLACK_CHANNEL_ID/${SLACK_CHANNEL_ID}/" | \
kubectl apply -f -
次にKaniko Build templateを作成し、Knative Serviceの構築に使わせます:
$ kubectl apply -f deploy/kaniko-buildtemplate.yml
$ kubectl get buildtemplate
NAME CREATED AT
kaniko 7s
完了したら、Knative serviceとIstio HTTPSサービス・エントリを作成してアプリケーションを提供し、それにPodがSlack HTTPs APIをアクセスできるようにします:
$ kubectl apply -f deploy/slack-https-sn.yml
$ kubectl apply -f deploy/slack-app-service.yml
$ kubectl get po -w
NAME READY STATUS RESTARTS AGE
slack-app-00001-9htqm 0/1 Init:2/3 0 8s
slack-app-00001-9htqm 0/1 Init:2/3 0 8s
slack-app-00001-9htqm 0/1 PodInitializing 0 3m
slack-app-00001-9htqm 0/1 Completed 0 4m
slack-app-00001-deployment-75f7f8dd8c-tskq8 0/3 Pending 0 0s
slack-app-00001-deployment-75f7f8dd8c-tskq8 0/3 Pending 0 0s
slack-app-00001-deployment-75f7f8dd8c-tskq8 0/3 Init:0/1 0 0s
slack-app-00001-deployment-75f7f8dd8c-tskq8 0/3 PodInitializing 0 7s
slack-app-00001-deployment-75f7f8dd8c-tskq8 2/3 Running 0 33s
knativeビルド関連のイメージ・ファイルをダウンロードする必要があるため、一回目の実行はより遅くなります。
ある程度の時間が経ったら、次のコマンドでサービスが正常であるかを確認します:
$ export IP_ADDRESS=$(minikube ip):$(kubectl get svc knative-ingressgateway -n istio-system -o 'jsonpath={.spec.ports[?(@.port==80)].nodePort}')
$ export DOMAIN=$(kubectl get services.serving.knative.dev slack-app -o=jsonpath='{.status.domain}')
# 透過 cURL 工具以 Get method 存取
$ curl -X GET -H "Host: ${DOMAIN}" ${IP_ADDRESS}
<h1>Hello slack app for Knative!!</h1>
# 透過 cURL 工具以 Post method 傳送 msg
$ curl -X POST \
-H 'Content-type: application/json' \
-H "Host: ${DOMAIN}" \
--data '{"msg":"Hello, World!"}' \
${IP_ADDRESS}
success
成功したら、Slackチャンネルがメッセージを送ったかを照会できます:
最後に、Knative Servingはリクエスト駆動型であるので、長い間リクエストがなければレプリカ数は自動的に0にまで減り、再びリクエストを受信してから一つのインスタンスを起動します。Knativeはほとんどの情報をPrometheusで監視するため、Prometheusを通じて状態の変化を観察できます。
まずはkubectlを通じてGrafana NodePortの情報を取得します:
$ kubectl -n monitoring get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
grafana NodePort 10.96.197.116 <none> 30802:30326/TCP 1h
prometheus-system-np NodePort 10.99.64.228 <none> 8080:32628/TCP 1h
...
ブラウザでhttp://minikube_ip:port を開いて照会します。
またはHTTPリクエストの状態を確認します。