Skip to main content

Cerbosのデプロイメントパターン

Cerbosは、様々な環境やアーキテクチャに対応するための柔軟なデプロイメントオプションを提供しています。ここでは、主要なデプロイメントパターンとそれぞれの特徴について説明します。

クラウドプラットフォーム #

AWS #

AWSでCerbosをデプロイする主な方法は以下の通りです:

  1. EC2インスタンス - 仮想マシン上でCerbosを実行
  2. ECS/Fargate - コンテナオーケストレーションサービスを使用
  3. EKS - マネージドKubernetesサービスを使用
  4. Lambda - サーバーレス環境で実行(制限あり)

EC2でのデプロイ例 #

# AMIからEC2インスタンスを起動
aws ec2 run-instances \
  --image-id ami-xxxxxxxxxx \
  --instance-type t3.micro \
  --key-name my-key-pair \
  --security-group-ids sg-xxxxxxxxxx

# SSHでインスタンスに接続
ssh -i my-key-pair.pem ec2-user@ec2-xx-xx-xx-xx.compute-1.amazonaws.com

# Cerbosをインストール
wget https://github.com/cerbos/cerbos/releases/download/v0.41.0/cerbos_0.41.0_Linux_x86_64.tar.gz
tar -xzf cerbos_0.41.0_Linux_x86_64.tar.gz

ECSでのデプロイ例 #

{
  "family": "cerbos",
  "executionRoleArn": "arn:aws:iam::xxxxxxxxxxxx:role/ecsTaskExecutionRole",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "name": "cerbos",
      "image": "ghcr.io/cerbos/cerbos:0.41.0",
      "essential": true,
      "command": ["server"],
      "portMappings": [
        {
          "containerPort": 3592,
          "hostPort": 3592,
          "protocol": "tcp"
        },
        {
          "containerPort": 3593,
          "hostPort": 3593,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/cerbos",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ],
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512"
}

Google Cloud Platform (GCP) #

GCPでCerbosをデプロイする主な方法は以下の通りです:

  1. Compute Engine - 仮想マシン上でCerbosを実行
  2. Google Kubernetes Engine (GKE) - マネージドKubernetesサービスを使用
  3. Cloud Run - コンテナをサーバーレスで実行

GKEでのデプロイ例 #

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cerbos
spec:
  replicas: 3
  selector:
    matchLabels:
      app: cerbos
  template:
    metadata:
      labels:
        app: cerbos
    spec:
      containers:
      - name: cerbos
        image: ghcr.io/cerbos/cerbos:0.41.0
        args: ["server"]
        ports:
        - containerPort: 3592
          name: http
        - containerPort: 3593
          name: grpc
        volumeMounts:
        - name: config
          mountPath: /config
        - name: policies
          mountPath: /policies
      volumes:
      - name: config
        configMap:
          name: cerbos-config
      - name: policies
        configMap:
          name: cerbos-policies
---
apiVersion: v1
kind: Service
metadata:
  name: cerbos
spec:
  selector:
    app: cerbos
  ports:
  - port: 3592
    name: http
  - port: 3593
    name: grpc
  type: ClusterIP

Microsoft Azure #

Azureでのデプロイオプションは以下の通りです:

  1. Azure Virtual Machines - 仮想マシン上でCerbosを実行
  2. Azure Kubernetes Service (AKS) - マネージドKubernetesサービスを使用
  3. Azure Container Instances - コンテナをサーバーレスで実行

Kubernetesパターン #

Kubernetesでは、以下の3つの主要なデプロイメントパターンがあります:

1. サービスとしてのデプロイ #

このパターンでは、Cerbosを独立したサービスとしてデプロイし、アプリケーションからネットワーク経由でアクセスします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cerbos
spec:
  replicas: 3
  selector:
    matchLabels:
      app: cerbos
  template:
    metadata:
      labels:
        app: cerbos
    spec:
      containers:
      - name: cerbos
        image: ghcr.io/cerbos/cerbos:0.41.0
        args: ["server"]
        ports:
        - containerPort: 3592
          name: http
        - containerPort: 3593
          name: grpc
---
apiVersion: v1
kind: Service
metadata:
  name: cerbos
spec:
  selector:
    app: cerbos
  ports:
  - port: 3592
    name: http
  - port: 3593
    name: grpc
  type: ClusterIP

メリット:

  • リソースの効率的な使用
  • 中央集権的な管理
  • スケーリングが容易

デメリット:

  • ネットワークレイテンシーが発生
  • 単一障害点になる可能性

2. サイドカーとしてのデプロイ #

このパターンでは、Cerbosをアプリケーションと同じPodにサイドカーコンテナとしてデプロイします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        ports:
        - containerPort: 8080
      - name: cerbos
        image: ghcr.io/cerbos/cerbos:0.41.0
        args: ["server"]
        ports:
        - containerPort: 3592
          name: http
        - containerPort: 3593
          name: grpc
        volumeMounts:
        - name: policies
          mountPath: /policies
      volumes:
      - name: policies
        configMap:
          name: cerbos-policies

メリット:

  • 低レイテンシー(localhost経由の通信)
  • アプリケーションごとに独立した構成が可能
  • 高可用性(アプリケーションと運命を共にする)

デメリット:

  • リソース使用量が増加
  • ポリシーの更新が複雑になる可能性

3. DaemonSetとしてのデプロイ #

このパターンでは、Cerbosをクラスタ内の各ノードに1つずつデプロイします。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: cerbos
spec:
  selector:
    matchLabels:
      app: cerbos
  template:
    metadata:
      labels:
        app: cerbos
    spec:
      containers:
      - name: cerbos
        image: ghcr.io/cerbos/cerbos:0.41.0
        args: ["server"]
        ports:
        - containerPort: 3592
          name: http
        - containerPort: 3593
          name: grpc
        volumeMounts:
        - name: policies
          mountPath: /policies
      volumes:
      - name: policies
        configMap:
          name: cerbos-policies

メリット:

  • ノードごとに1つのインスタンスで効率的
  • 低レイテンシー(同一ノード内の通信)
  • スケーリングが自動的(ノードの追加に伴い自動的にデプロイ)

デメリット:

  • ノードリソースの使用量が増加
  • ポリシーの更新が複雑になる可能性

サーバーレス/FaaS環境 #

サーバーレス環境でCerbosを使用する方法は以下の通りです:

1. 外部サービスとしてのCerbos #

サーバーレス関数から外部のCerbosサービスを呼び出します。

// AWS Lambda関数の例
const { GRPC: Cerbos } = require("@cerbos/grpc");

exports.handler = async (event) => {
  const cerbos = new Cerbos("cerbos-service.example.com:3593", { tls: true });
  
  const decision = await cerbos.checkResource({
    principal: {
      id: event.userId,
      roles: event.userRoles,
      attributes: event.userAttributes,
    },
    resource: {
      kind: event.resourceKind,
      id: event.resourceId,
      attributes: event.resourceAttributes,
    },
    actions: event.actions,
  });
  
  return {
    statusCode: 200,
    body: JSON.stringify({
      allowed: decision.isAllowed(event.actions[0]),
    }),
  };
};

2. 組み込みCerbos #

Cerbosをライブラリとして関数に組み込みます(現在は実験的な機能)。

// 組み込みCerbosの例(実験的)
const { Embedded: Cerbos } = require("@cerbos/embedded");

let cerbos;

exports.handler = async (event) => {
  if (!cerbos) {
    cerbos = new Cerbos({
      policies: process.env.POLICIES_DIR,
    });
    await cerbos.init();
  }
  
  const decision = await cerbos.checkResource({
    principal: {
      id: event.userId,
      roles: event.userRoles,
      attributes: event.userAttributes,
    },
    resource: {
      kind: event.resourceKind,
      id: event.resourceId,
      attributes: event.resourceAttributes,
    },
    actions: event.actions,
  });
  
  return {
    statusCode: 200,
    body: JSON.stringify({
      allowed: decision.isAllowed(event.actions[0]),
    }),
  };
};

systemdサービス #

LinuxシステムでCerbosをsystemdサービスとして実行する方法は以下の通りです:

  1. サービス定義ファイルを作成します:
cat > /etc/systemd/system/cerbos.service <<EOF
[Unit]
Description=Cerbos Policy Decision Point
After=network.target

[Service]
User=cerbos
Group=cerbos
ExecStart=/usr/local/bin/cerbos server --config=/etc/cerbos/config.yaml
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF
  1. サービスを有効化して起動します:
systemctl daemon-reload
systemctl enable cerbos
systemctl start cerbos
  1. サービスのステータスを確認します:
systemctl status cerbos

高可用性の構成 #

本番環境では、高可用性を確保するために以下の点を考慮する必要があります:

  1. 複数のインスタンス - 少なくとも3つのCerbosインスタンスを異なるアベイラビリティゾーンにデプロイ
  2. ロードバランシング - リクエストを複数のインスタンスに分散
  3. ヘルスチェック - 定期的なヘルスチェックで障害を検出
  4. 自動スケーリング - 負荷に応じてインスタンス数を調整
  5. ポリシーの一貫性 - すべてのインスタンスで同じポリシーが使用されるようにする

Kubernetesでの高可用性構成例 #

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cerbos
spec:
  replicas: 3
  selector:
    matchLabels:
      app: cerbos
  template:
    metadata:
      labels:
        app: cerbos
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - cerbos
              topologyKey: kubernetes.io/hostname
      containers:
      - name: cerbos
        image: ghcr.io/cerbos/cerbos:0.41.0
        args: ["server"]
        ports:
        - containerPort: 3592
          name: http
        - containerPort: 3593
          name: grpc
        livenessProbe:
          httpGet:
            path: /health
            port: 3592
          initialDelaySeconds: 5
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 3592
          initialDelaySeconds: 5
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: cerbos
spec:
  selector:
    app: cerbos
  ports:
  - port: 3592
    name: http
  - port: 3593
    name: grpc
  type: ClusterIP
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: cerbos
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: cerbos
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

Cerbos Hubとの統合 #

Cerbos Hubは、ポリシーの管理、デプロイ、監視を容易にするマネージドサービスです。Cerbos Hubと統合するには、以下の設定を行います:

server:
  httpListenAddr: ":3592"
  grpcListenAddr: ":3593"

hub:
  credentials:
    pdpID: "my-pdp"
    clientID: "client-id"
    clientSecret: "client-secret"
    workspaceSecret: "workspace-secret"

storage:
  driver: hub
  hub:
    remote:
      bundleLabel: latest

監視と可観測性 #

Cerbosは、Prometheus、OpenTelemetry、Grafanaなどの一般的な監視ツールと統合できます。

Prometheusメトリクスの有効化 #

server:
  httpListenAddr: ":3592"
  grpcListenAddr: ":3593"

telemetry:
  metrics:
    enabled: true
    prometheus:
      path: "/metrics"

OpenTelemetryトレースの有効化 #

server:
  httpListenAddr: ":3592"
  grpcListenAddr: ":3593"

telemetry:
  traces:
    enabled: true
    otlp:
      endpoint: "otel-collector:4317"

まとめ #

Cerbosは、様々なデプロイメント環境やアーキテクチャに対応する柔軟なオプションを提供しています。アプリケーションの要件、パフォーマンス要件、運用モデルに基づいて、最適なデプロイメントパターンを選択することが重要です。高可用性、スケーラビリティ、監視を考慮した構成を行うことで、本番環境での信頼性の高いアクセス制御システムを構築できます。

[出典: https://docs.cerbos.dev/cerbos/latest/deployment/]