#はじめに
ここには、kindセットアップ済みの環境にKnativeをインストールする手順を記録しておきます。
kindのセットアップは別記事「Linux環境でKubernetesクラスターを動かす」にまとめてます。
今回の環境はこちら:
Ubuntu 20.04.3
Docker version 20.10.12
kubectl version 1.23.0
kind version 0.11.1
Knative version 1.1.0
#インストール手順
公式のInstalling Knativeや、Blog: How to set up a local Knative environment with KinD and without DNS headachesあたりの情報を参考にKnativeをセットアップしていきます。
###Kubernetesクラスターの作成
Knative用のクラスターを作成します。まずは設定ファイルを作成して、Ingressへアクセスするポート番号をextraPortMappingsで設定します。
$ cat > clusterconfig.yaml <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
## expose port 31080 of the node to port 80 on the host
- containerPort: 31080
hostPort: 80
## expose port 31443 of the node to port 443 on the host
- containerPort: 31443
hostPort: 443
EOF
ここでは、ホスト上の80番ポートをコンテナーの31080に、443ポートを31443にマッピングしています。
次にこの設定ファイルを使って、クラスターを作成します。
$ sudo kind create cluster --name knative --config clusterconfig.yaml
Creating cluster "knative" ...
✓ Ensuring node image (kindest/node:v1.21.1) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-knative"
You can now use your cluster with:
kubectl cluster-info --context kind-knative
Thanks for using kind! 😊
###Knative Servingのインストール
KnativeにはKnative EventingというEvent-Driven用のコンポーネントもありますが、今回はRequest-Replyモデルのアプリケーションが動けばいいのでKnative Servingだけインストールします。
- CRD(Custom Resource Definition)のApply
$ sudo kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.1.0/serving-crds.yaml
ログ
ustomresourcedefinition.apiextensions.k8s.io/certificates.networking.internal.knative.dev created
customresourcedefinition.apiextensions.k8s.io/configurations.serving.knative.dev created
customresourcedefinition.apiextensions.k8s.io/clusterdomainclaims.networking.internal.knative.dev created
customresourcedefinition.apiextensions.k8s.io/domainmappings.serving.knative.dev created
customresourcedefinition.apiextensions.k8s.io/ingresses.networking.internal.knative.dev created
customresourcedefinition.apiextensions.k8s.io/metrics.autoscaling.internal.knative.dev created
customresourcedefinition.apiextensions.k8s.io/podautoscalers.autoscaling.internal.knative.dev created
customresourcedefinition.apiextensions.k8s.io/revisions.serving.knative.dev created
customresourcedefinition.apiextensions.k8s.io/routes.serving.knative.dev created
customresourcedefinition.apiextensions.k8s.io/serverlessservices.networking.internal.knative.dev created
customresourcedefinition.apiextensions.k8s.io/services.serving.knative.dev created
customresourcedefinition.apiextensions.k8s.io/images.caching.internal.knative.dev created
- Knative Serving Core Componentのインストール
$ sudo kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.1.0/serving-core.yaml
ログ
namespace/knative-serving created
clusterrole.rbac.authorization.k8s.io/knative-serving-aggregated-addressable-resolver created
clusterrole.rbac.authorization.k8s.io/knative-serving-addressable-resolver created
clusterrole.rbac.authorization.k8s.io/knative-serving-namespaced-admin created
clusterrole.rbac.authorization.k8s.io/knative-serving-namespaced-edit created
clusterrole.rbac.authorization.k8s.io/knative-serving-namespaced-view created
clusterrole.rbac.authorization.k8s.io/knative-serving-core created
clusterrole.rbac.authorization.k8s.io/knative-serving-podspecable-binding created
serviceaccount/controller created
clusterrole.rbac.authorization.k8s.io/knative-serving-admin created
clusterrolebinding.rbac.authorization.k8s.io/knative-serving-controller-admin created
clusterrolebinding.rbac.authorization.k8s.io/knative-serving-controller-addressable-resolver created
customresourcedefinition.apiextensions.k8s.io/images.caching.internal.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/certificates.networking.internal.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/configurations.serving.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/clusterdomainclaims.networking.internal.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/domainmappings.serving.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/ingresses.networking.internal.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/metrics.autoscaling.internal.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/podautoscalers.autoscaling.internal.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/revisions.serving.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/routes.serving.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/serverlessservices.networking.internal.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/services.serving.knative.dev unchanged
image.caching.internal.knative.dev/queue-proxy created
configmap/config-autoscaler created
configmap/config-defaults created
configmap/config-deployment created
configmap/config-domain created
configmap/config-features created
configmap/config-gc created
configmap/config-leader-election created
configmap/config-logging created
configmap/config-network created
configmap/config-observability created
configmap/config-tracing created
horizontalpodautoscaler.autoscaling/activator created
Warning: policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget
poddisruptionbudget.policy/activator-pdb created
deployment.apps/activator created
service/activator-service created
deployment.apps/autoscaler created
service/autoscaler created
deployment.apps/controller created
service/controller created
deployment.apps/domain-mapping created
deployment.apps/domainmapping-webhook created
service/domainmapping-webhook created
horizontalpodautoscaler.autoscaling/webhook created
poddisruptionbudget.policy/webhook-pdb created
deployment.apps/webhook created
service/webhook created
validatingwebhookconfiguration.admissionregistration.k8s.io/config.webhook.serving.knative.dev created
mutatingwebhookconfiguration.admissionregistration.k8s.io/webhook.serving.knative.dev created
mutatingwebhookconfiguration.admissionregistration.k8s.io/webhook.domainmapping.serving.knative.dev created
secret/domainmapping-webhook-certs created
validatingwebhookconfiguration.admissionregistration.k8s.io/validation.webhook.domainmapping.serving.knative.dev created
validatingwebhookconfiguration.admissionregistration.k8s.io/validation.webhook.serving.knative.dev created
secret/webhook-certs created
###ネットワーク・レイヤーのインストール
以前はKnativeのネットワークといえばIstioだったようですが、今では選択肢が増えています。今回はKourierという軽量なIngressを使って外部からクラスターへのアクセスを制御します。
- yamlファイルをダウンロード
ローカル構成用にカスタマイズするため、kourier.yamlファイルをダウンロードします。
$ curl -Lo kourier.yaml https://github.com/knative/net-kourier/releases/download/knative-v1.1.0/kourier.yaml
- yamlファイルの編集
type: LoadBalancerをnodePortに変更します。
apiVersion: v1
kind: Service
metadata:
name: kourier
namespace: kourier-system
labels:
networking.knative.dev/ingress-provider: kourier
app.kubernetes.io/component: net-kourier
app.kubernetes.io/version: "1.1.0"
app.kubernetes.io/name: knative-serving
serving.knative.dev/release: "v1.1.0"
spec:
ports:
- name: http2
port: 80
protocol: TCP
targetPort: 8080
nodePort: 31080 # 追加
- name: https
port: 443
protocol: TCP
targetPort: 8443
nodePort: 31443 # 追加
selector:
app: 3scale-kourier-gateway
type: NodePort # LoadBalancerから変更
- Kourierコントローラーをインストールします。
$ sudo kubectl apply --filename kourier.yaml
ログ
namespace/kourier-system created
configmap/kourier-bootstrap created
configmap/config-kourier created
serviceaccount/net-kourier created
clusterrole.rbac.authorization.k8s.io/net-kourier created
clusterrolebinding.rbac.authorization.k8s.io/net-kourier created
deployment.apps/net-kourier-controller created
service/net-kourier-controller created
deployment.apps/3scale-kourier-gateway created
service/kourier created
service/kourier-internal created
- Knative ServingがKourierを使用するように構成します。
$ sudo kubectl patch configmap/config-network \
--namespace knative-serving \
--type merge \
--patch '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'
設定が正しく反映されているかは以下のコマンドで確認できます。
$ sudo kubectl describe configmap/config-network --namespace knative-serving
(省略)
ingress-class:
----
kourier.ingress.networking.knative.dev
(省略)
###DNSの構成
ここではワイルドカードDNSサービスであるsslip.ioを使用するよう構成します。
$ sudo kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.1.0/serving-default-domain.yaml
job.batch/default-domain created
service/default-domain-service created
config-domainに以下を追加して、カスタム・ドメイン"*.127.0.0.1.sslip.io"を127.0.0.1に解決します。
$ kubectl patch configmap/config-domain \
--namespace knative-serving \
--type merge \
--patch '{"data":{"127.0.0.1.sslip.io":""}}'
configmap/config-domain patched
設定が正しく反映されているかは以下のコマンドで確認できます。
$ sudo kubectl describe configmap/config-domain --namespace knative-serving
(抜粋)
Data
====
127.0.0.1.sslip.io:
----
###Knativeコンポーネントの稼働確認
pod一覧を表示して、すべてのpodがRunningまたはCompleted STATUSになっていることを確認します。以下は出力例です (pod名など環境によって異なります)。
$ sudo kubectl get pods -n knative-serving
NAME READY STATUS RESTARTS AGE
activator-6fb68fff7b-cqgbx 1/1 Running 0 18m
autoscaler-54f48f5bb7-bwfls 1/1 Running 0 18m
controller-66cb4b556b-649sl 1/1 Running 0 18m
domain-mapping-66f8d5bc4c-vh7c2 1/1 Running 0 18m
domainmapping-webhook-55bdf595dd-gwdjr 1/1 Running 0 18m
net-kourier-controller-7df5866d8d-cvhh9 1/1 Running 0 3m8s
webhook-6d5c77f989-qq4gk 1/1 Running 0 18m
$ sudo kubectl get pods -n kourier-system
NAME READY STATUS RESTARTS AGE
3scale-kourier-gateway-58856c6cc7-qqp69 1/1 Running 0 3m30s
設定通りにポート番号が使用されていることを確認します。
$ sudo kubectl --namespace kourier-system get service kourier
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kourier NodePort 10.96.152.240 <none> 80:31080/TCP,443:31443/TCP 4m36s
goma@gomagame-ub:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7f672d87425 kindest/node:v1.21.1 "/usr/local/bin/entr…" 22 minutes ago Up 22 minutes 127.0.0.1:38523->6443/tcp, 0.0.0.0:80->31080/tcp, 0.0.0.0:443->31443/tcp knative-control-plane
#サンプル・アプリケーションの実行
GitHub knative/docsにはKnativeのサンプル・アプリなどが色々公開されています。その中のKnative Serving用サンプル、helloworld-goアプリを動かしてみます。
- GitHubリポジトリーをローカルにclone
$ git clone https://github.com/knative/docs.git knative-docs
Cloning into 'knative-docs'...
remote: Enumerating objects: 36892, done.
remote: Counting objects: 100% (141/141), done.
remote: Compressing objects: 100% (119/119), done.
remote: Total 36892 (delta 47), reused 31 (delta 11), pack-reused 36751
Receiving objects: 100% (36892/36892), 54.71 MiB | 13.18 MiB/s, done.
Resolving deltas: 100% (23693/23693), done.
goma@gomagame-ub:~$ cd knative-docs/code-samples/serving/hello-world/helloworld-go
これ以降は、knative-docs/code-samples/serving/hello-world/helloworld-goディレクトリーで作業します。
Docker build & push
ローカルでコンテナーをBuildして、Docker HubへPushします。
ここで{username}はDocker Hubのユーザー名を指定します。Docker Hubのアカウントを持っていない場合は、Docker HubサイトでSign Upしてアカウントを作成しておきましょう。
$ sudo docker build -t {username}/helloworld-go .
$ sudo docker push {username}/helloworld-go
pushする前にdocker login
しておくこともお忘れなく。
Deploy
Buid & Pushしたアプリをクラスターにデプロイします。
まずはservice.yamlファイルを編集して、{username}の部分を自分のDocker Hubユーザー名に書き換えておきます。
$ vi service.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
spec:
containers:
- image: docker.io/{username}/helloworld-go
env:
- name: TARGET
value: "Go Sample v1"
service.yamlをapplyすると、アプリがデプロイされます。
$ sudo kubectl apply --filename service.yaml
service.serving.knative.dev/helloworld-go configured
###実行
以下のコマンドでURLを調べます。
$ sudo kubectl get ksvc helloworld-go
(出力例)
NAME URL LATESTCREATED LATESTREADY READY REASON
helloworld-go http://helloworld-go.default.127.0.0.1.sslip.io helloworld-go-00001 helloworld-go-00001 True
リクエストを実行します。
以下のように、Helloメッセージが表示されれば成功です。
$ curl http://helloworld-go.default.127.0.0.1.sslip.io
Hello Go Sample v1!
###クラスターの削除
要らなくなったknativeクラスターは以下のコマンドで削除できます。
$ sudo kind delete cluster --name knative
#まとめ
kindとKnativeで簡単にローカルサーバーレス環境を構築することができました。お次は、サーバーレス・アプリケーションを作ってこの環境で動かしてみたいと思います。