5
2

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 1 year has passed since last update.

kind + Knativeでローカルにサーバーレス環境をつくる

Last updated at Posted at 2021-12-20

#はじめに

ここには、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に変更します。

(抜粋)kourier.yaml
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
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で簡単にローカルサーバーレス環境を構築することができました。お次は、サーバーレス・アプリケーションを作ってこの環境で動かしてみたいと思います。

5
2
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
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?