Open6

Kind × Skaffold × Istio 検証

ピン留めされたアイテム
Tomonori Hayashi / @pHaya72Tomonori Hayashi / @pHaya72

Kind とは?

  • Kubernetes in Docker の略称
  • Kubernetes のクラスターはコントロールプレーンと複数のデータプレーンで構成される
    • GKE とかはこれらノードが Compute Engine で構成されている
    • Kind ではこれらノードが Docker コンテナで構成されている
  • ノードの役割を果たす Docker コンテナ上でコンテナランタイム(コンテナイメージを実行させるソフトウェアでここでは containerd)が起動していて、このコンテナランタイムが Kubernetes コンポーネントやアプリケーションをコンテナとして管理している

  • 公式ドキュメントでの説明は下記。

"kind is a tool for running local Kubernetes clusters using Docker container “nodes”.
kind was primarily designed for testing Kubernetes itself, but may be used for local development or CI.
If you have go 1.16+ and docker, podman or nerdctl installed go install sigs.k8s.io/kind@v0.23.0 && kind create cluster is all you need!"

"kind は、Docker コンテナを「ノード」として使用するローカルの Kubernetes クラスターを実行するためのツールです。
kind は主に Kubernetes 自体のテストのために設計されましたが、ローカル開発や CI でも使用できます。
go 1.16 以降と Docker、podman または nerdctl がインストールされている場合は、go install sigs.k8s.io/kind@v0.23.0 && kind create cluster を実行するだけで済みます!"

ユースケース

  • 上記にもある通り、テストのために設計されていたが、ローカルでの開発でも有用
  • 実際に使ってみたが、容易に Kubernetes 環境を構築/削除できるし、Skaffold と組み合わせるとかなり良い開発体験となる(所感)

Skaffold とは?

  • コンテナベース及び Kubernetes アプリケーションの継続的な開発を容易にする OSS コマンドツール
  • Google が開発元であるため、Google Cloudの一部サービスで利用されている
    • Cloud Build 内でSkaffoldを使用したビルド / テスト / デプロイ
    • Cloud DeployでSkaffoldマニュフェストのデプロイ定義をレンダリング
  • ビルドからデプロイまでのパイプラインを定義しておき、実行し続けてくれる
    • どうやって実行し続けてくれるかというと、変更を勝手に検知して再実行してくれる
      → いわゆるホットリロード機能を提供してくれる

ユースケース

  • ビルドからデプロイまでのパイプラインを定義することから CI/CD パイプラインで利用される
  • Kind と組み合わせることでローカルでのアプリケーション開発が爆走になる(所感)
Tomonori Hayashi / @pHaya72Tomonori Hayashi / @pHaya72

準備

環境構築

  • kind-config.yaml を用意して kind create cluster --config kind/kind-config.yaml --name kind-cluster で構築する
    • extraPortMapping を設定すると control-plane のコンテナが指定ポートで外部向けに公開される
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 8080
- role: worker
  extraMounts:
  - containerPath: /mnt
    hostPath: ./
- role: worker
  extraMounts:
  - containerPath: /mnt
    hostPath: ./
  • 作成後に kind get kubeconfig --name kind-cluster で kubeconfig を取得
Tomonori Hayashi / @pHaya72Tomonori Hayashi / @pHaya72

アプリデプロイ

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi-sample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fastapi-sample
  template:
    metadata:
      labels:
        app: fastapi-sample
    spec:
      containers:
      - name: fastapi-sample
        image: fastapi-sample
        ports:
        - containerPort: 8080
        volumeMounts:
        - mountPath: /app
          name: test-volume
      volumes:
      - name: test-volume
        hostPath:
          path: /mnt
          type: Directory
---
apiVersion: v1
kind: Service
metadata:
  name: fastapi-sample-service
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 30000
  selector:
    app: fastapi-sample
Tomonori Hayashi / @pHaya72Tomonori Hayashi / @pHaya72

マルチでデプロイ

  • front → service-bff → (service-a, service-b) の構成でデプロイする
    • service-bff:8080
    • service-a:8081
    • service-b:8082

kind

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 8080
  - containerPort: 30001
    hostPort: 8081
  - containerPort: 30002
    hostPort: 8082
- role: worker
  extraMounts:
  - containerPath: /mnt
    hostPath: ./
- role: worker
  extraMounts:
  - containerPath: /mnt
    hostPath: ./

backend for frontend

  • bff に加えて他の service もデプロイ
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-for-frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend-for-frontend
  template:
    metadata:
      labels:
        app: backend-for-frontend
    spec:
      containers:
      - name: backend-for-frontend
        image: backend-for-frontend
        ports:
        - containerPort: 8080
        volumeMounts:
        - mountPath: /app
          name: src-volume
      volumes:
      - name: src-volume
        hostPath:
          path: /mnt/service-backend-for-frontend
          type: Directory
---
apiVersion: v1
kind: Service
metadata:
  name: service-backend-for-frontend
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 30000
  selector:
    app: backend-for-frontend

Tomonori Hayashi / @pHaya72Tomonori Hayashi / @pHaya72

otel-collector をデプロイ

kind

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 8080
  - containerPort: 30001
    hostPort: 8081
  - containerPort: 30002
    hostPort: 8082
  - containerPort: 30003
    hostPort: 4317
- role: worker
  extraMounts:
  - containerPath: /mnt
    hostPath: ./
- role: worker
  extraMounts:
  - containerPath: /mnt
    hostPath: ./

otel-collector

apiVersion: apps/v1
kind: Deployment
metadata:
  name: otel-collector
spec:
  replicas: 1
  selector:
    matchLabels:
      app: otel-collector
  template:
    metadata:
      labels:
        app: otel-collector
    spec:
      containers:
      - name: otel-collector
        image: otel-collector
        ports:
        - containerPort: 4317
---
apiVersion: v1
kind: Service
metadata:
  name: service-otel-collector
spec:
  type: NodePort
  ports:
  - port: 4317
    targetPort: 4317
    nodePort: 30003
  selector:
    app: otel-collector
Tomonori Hayashi / @pHaya72Tomonori Hayashi / @pHaya72

helm で istio インストール & アクセス制御

helm

istioctl

  • brew install istioctl

istio

Layer 4 authorization policy

  • Success : bff → service-b
  • Fail : bff → service-a → service-b
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: allow-bff-to-backend-b
spec:
 selector:
   matchLabels:
     app: backend-b
 action: ALLOW
 rules:
 - from:
   - source:
      principals:
      - cluster.local/ns/default/sa/bff-serviceaccouunt

visualization

opentelemetry