> ## Documentation Index
> Fetch the complete documentation index at: https://docs.automq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 Helm Chart 部署 AutoMQ Software

> 通过 Helm Chart 在私有 Kubernetes 数据中心部署 AutoMQ Software，支持灵活存储选项、100% Kafka 兼容性和高效运维。

本文档介绍如何在企业私有数据中心的 Kubernetes 环境中使用 Helm Chart 部署 AutoMQ Software。如果期望在公共云环境使用 AutoMQ，推荐直接使用 AutoMQ Cloud 全托管服务[概述▸](/zh/automq-cloud/getting-started/overview)。

## 前置条件

使用 Helm Chart 安装 AutoMQ 之前，需要满足如下条件：

1. **准备 Kubernetes 环境** ：提前准备一个可用的 Kubernetes 集群，并满足如下条件：

   1. **预留 AutoMQ 计算资源** ：AutoMQ 每个 Pod 推荐分配 4Core16GB 资源，并建议独占 Node 部署以获取稳定的网络吞吐性能。

   2. **存储插件：** 如果您的 Kubernetes 由云厂商提供，推荐安装云厂商提供的存储插件用于管理 EBS 卷资源。

2. **准备对象存储 Bucket。** AutoMQ 每个集群需要 2 个独立的对象存储 Bucket，一个是 Ops Bucket 用于存储系统日志和 Metrics 数据，一个是 Data Bucket 存储消息数据。请参考对象存储产品的文档创建。

3. **安装 Helm Chart 工具：** 推荐安装大于等于 3.6 版本。可[参考文档](https://helm.sh/zh/docs/intro/quickstart/)操作。

## 获取 AutoMQ Software Chart

AutoMQ Software Chart 镜像通过 Azure Container Registry (East US) 镜像仓库进行发布和公开。您可以通过如下命令进行拉取测试。

```bash theme={null}

helm pull oci://automq.azurecr.io/helm/automq-enterprise-chart --version 5.3.4

```

## 安装 AutoMQ

AutoMQ Software 提供两种 WAL 存储类型，分别是 EBSWAL 和 S3WAL，两种存储引擎对比如下，建议根据需求选择。详细原理请参考[技术架构](https://docs.automq.com/automq/architecture/s3stream-shared-streaming-storage/wal-storage)。

* **EBSWAL 模式：** WAL 存储使用高速 EBS 卷，提供 \<10 毫秒的发送 RT 性能，目前仅支持 AWS、GCP、Azure 等公共云环境，使用时需要通过 StorageClass，为 AutoMQ 的 Pod 分配 EBS 卷。

* **S3WAL 模式：** 部署相对简单，WAL 存储直接写对象存储，提供百毫秒级的发送 RT 性能，支持所有公共云环境以及私有数据中心（提供兼容 S3 的对象存储即可），部署相对简单，无需分配 EBS 卷。

<Tip>
  下方章节提供的各个云厂商环境下的一个简易部署场景示例。该示例场景部署S3WAL 模式，使用静态 Credentials 访问云资源，支持使用 Headless 接入点在 Kubernetes 集群内访问 AutoMQ 或者使用 LoadBalancer 接入点在 Kubernetes 集群外访问 AutoMQ。

  AutoMQ 团队同时提供了包括 TLS、认证授权、Auto-Scaler 等多种高阶功能示例，详情请参考[高阶功能示例 ▸](https://github.com/AutoMQ/automq-labs/tree/main/software-examples/kubernetes/)。
</Tip>

### Step1：创建 Credentials，并进行授权

AutoMQ 集群需要访问对象存储和存储卷等外部服务，因此在安装前需要为 AutoMQ 创建 Credentials 并完成授权。

<Tabs>
  <Tab title="AWS">
    AWS 公共云环境部署 AutoMQ 且使用 AWS S3 存储，则需要前往 IAM 产品创建授权策略，AutoMQ 访问 AWS S3 需要被授予以下操作权限：

    ```yaml theme={null}

    - actions:
        - s3:GetLifecycleConfiguration
        - s3:PutLifecycleConfiguration
        - s3:ListBucket
        - s3:PutObject
        - s3:GetObject
        - s3:AbortMultipartUpload
        - s3:PutObjectTagging
        - s3:DeleteObject

    ```

    如果您使用 EBSWAL  模式部署，则需要额外授权如下策略：

    ```yaml theme={null}

    - actions:
        - ec2:DescribeVolumes
        - ec2:DetachVolume
        - ec2:DescribeAvailabilityZones

    ```

    用户创建 IAM 授权策略后，可以通过以下两种方式创建 Credentials。

    * **使用 IAM 子账号静态 AccessKey：** 此模式下需要将授权策略附加给 IAM 子账号，并通过 IAM 子账号的静态 AccessKeyId 和 AccessKeySecret 作为 Credentials 访问 AutoMQ。

    * **使用 IAM Role 动态凭证 ：** 此模式下需要创建 IAM Role，需要将授权策略附加给 Role。然后在 EKS 上通过 Pod 扮演 EC2 Role 的动态 Credentials 访问 AutoMQ。

    <Tip>
      本示例的配置文件示例使用静态 AccessKey 作为 Credentials。
    </Tip>
  </Tab>

  <Tab title="Azure">
    Azure 公共云环境部署AutoMQ使用Azure Blob存储，需要前往Storage Account的访问控制（IAM）创建授权 Credential。用户可选择以下两种权限实体（任意一个），进行Blob的系统角色分配： `Storage Blob Data Owner` 。

    * **使用服务主体（Service Principal）静态Secret** ：其中 AccessKey 为所属 App clientId，SecretKey 为 Secret value、tenantId共同作为静态 Credentials 访问 AutoMQ。

    * **使用身份标识（Managed Identity）动态凭证** ：此模式下除了被 ServiceAccount 分配相应角色之外，需要额外关联 AutoMQ 对应的 vmss（虚拟节点组）。然后在 AKS 上通过此动态凭证的 clientId 访问AutoMQ。
  </Tab>

  <Tab title="OCI">
    在 OCI 环境部署 AutoMQ，您需要前往 Identity & Security 页面为用户生成一个 **Customer Secret Key** 作为静态凭证。该用户必须被授予访问对象存储 (Object Storage) 的相应权限。

    首先，为管理 AutoMQ 的用户或用户组创建以下 IAM 授权策略：

    ```text theme={null}
    Allow group <your-group-name> to manage objects in compartment <your-compartment> where any {
      target.bucket.name = '<your-data-bucket>',
      target.bucket.name = '<your-ops-bucket>'
    }

    Allow group <your-group-name> to use buckets in compartment <your-compartment> where any {
      target.bucket.name = '<your-data-bucket>',
      target.bucket.name = '<your-ops-bucket>'
    }
    ```

    * `manage objects` 权限集包含了对对象的创建、读取、删除和列出等操作。
    * `use buckets` 权限集包含了对存储桶生命周期策略的管理权限。

    如果您计划使用 **EBSWAL** 模式，OKE 的工作节点需要权限来管理块存储 (Block Volume)。请确保为您的节点池创建一个动态组 (Dynamic Group)，并为其授予以下权限：

    ```text theme={null}
    Allow dynamic-group <your-node-dynamic-group> to manage block-volumes in compartment <your-compartment>
    Allow dynamic-group <your-node-dynamic-group> to manage volume-attachments in compartment <your-compartment>
    Allow dynamic-group <your-node-dynamic-group> to use subnets in compartment <your-compartment>
    Allow dynamic-group <your-node-dynamic-group> to inspect instances in compartment <your-compartment>
    ```

    创建凭证后，记录下 **Access Key** 和 **Secret Key**，它们将用作后续 Helm Chart 配置中的静态 Credentials。
  </Tab>
</Tabs>

### Step2：创建 Storage Class

安装 AutoMQ 之前需要在 Kubernetes 集群申明 Storage Class，用于后续分配存储卷。存储卷有以下用途：

* **存储 AutoMQ Controller 元数据：** AutoMQ 集群中用于元数据管理的 Controller Pod 需要挂载存储卷存储 KRaft 元数据。

* **EBSWAL 模式存储 WAL 数据（可选）** ：如果期望部署 EBSWAL 模式，每个 Broker Pod 也需要挂载数据卷用于写入 WAL 数据。

<Tip>
  请根据云厂商或者私有数据中心的 Kubernetes 存储插件申明 Storage Class ，然后记录该 Storage Class 名称，用于后续参数配置。
</Tip>

<Tabs>
  <Tab title="AWS">
    ```yaml theme={null}

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: automq-disk-eks-gp3
    provisioner: ebs.csi.aws.com
    volumeBindingMode: WaitForFirstConsumer
    parameters:
      type: gp3  # EBS volume type
    allowVolumeExpansion: true

    ```
  </Tab>

  <Tab title="Azure">
    ```yaml theme={null}

    # Example StorageClass definition (Azure Premium SSD example)  
    apiVersion: storage.k8s.io/v1  
    kind: StorageClass  
    metadata:  
      name: automq-disk-storage-class
    provisioner: disk.csi.azure.com  
    parameters:  
      skuName: PremiumV2_LRS  
    reclaimPolicy: Delete  
    volumeBindingMode: WaitForFirstConsumer  
    allowVolumeExpansion: true  

    ```
  </Tab>

  <Tab title="GCP">
    ```yaml theme={null}

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: automq-disk-gcp-pd-balanced
    provisioner: pd.csi.storage.gke.io
    volumeBindingMode: WaitForFirstConsumer
    allowVolumeExpansion: true
    parameters:
      type: pd-balanced  # High performance cloud disk.

    ```
  </Tab>

  <Tab title="OCI">
    ```yaml theme={null}
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: automq-block-volume
    provisioner: blockvolume.csi.oraclecloud.com
    reclaimPolicy: Delete
    volumeBindingMode: WaitForFirstConsumer
    allowVolumeExpansion: true
    parameters:
      # vpusPerGB 决定了存储卷的 IOPS 和吞吐性能
      # 10: 提供基础性能
      # 20: 提供更高的性能，推荐用于生产环境
      vpusPerGB: "20"
      # attachmentType 决定了卷的挂载类型
      # iscsi: iSCSI 挂载，通用
      # paravirtualized: 半虚拟化挂载，提供更高性能
      attachmentType: "paravirtualized"
    ```
  </Tab>
</Tabs>

### Step3：初始化配置文件

AutoMQ Software Chart 的配置信息包含多个部分，支持用户通过 values.yaml 文件进行自定义覆盖。

<Tip>
  **必填：设置唯一的实例 ID**

  您必须定义一个关键参数 `global.automqInstanceId`。这是您的 AutoMQ 集群的**必填**唯一标识符。

  为什么它很重要？此 ID 可确保资源被正确隔离，防止数据损坏或冲突。每个集群都必须有自己独特的 `automqInstanceId`。
</Tip>

首先，需要创建一个空文件   `automq-values.yaml` 。您可以复制下方给出的示例配置进行编辑替换。

```yaml theme={null}

global:
  cloudProvider:
    name: "Replace With Your True Cloud Provider Name"
    credentials: "Replace With Your True Your Credentials"
  config: |
    s3.ops.buckets=Replace With Your True Ops Bucket URL
    s3.data.buckets=Replace With Your True Data Bucket URL
    s3.wal.path=Replace With Your True WAL PATH

controller:
  resources:
    requests:
      cpu: "3000m"
      memory: "12Gi"
    limits:
      cpu: "4000m"
      memory: "16Gi"
  persistence:
    metadata:
      storageClass: "Replace With Your True StroageClass"
    wal:
      enabled: false

  annotations:

  env:
    - name: "KAFKA_JVM_PERFORMANCE_OPTS"
      value: "-server -XX:+UseZGC -XX:ZCollectionInterval=5"
    - name: "KAFKA_OPTS"
      value: "-XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError"
    - name: "KAFKA_HEAP_OPTS"
      value: "-Xmx6g -Xms6g -XX:MaxDirectMemorySize=6g -XX:MetaspaceSize=96m"
    - name: "KAFKA_S3_ACCESS_KEY"
      value: "Replace With Your True ACCESS_KEY"
    - name: "KAFKA_S3_SECRET_KEY"
      value: "Replace With Your True SECRET_KEY"

broker:
  replicas: 0
  resources:
    requests:
      cpu: "3000m"
      memory: "12Gi"
    limits:
      cpu: "4000m"
      memory: "16Gi"

  persistence:
    wal:
      enabled: false

  annotations:

  env:
    - name: "KAFKA_JVM_PERFORMANCE_OPTS"
      value: "-server -XX:+UseZGC -XX:ZCollectionInterval=5"
    - name: "KAFKA_OPTS"
      value: "-XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError"
    - name: "KAFKA_HEAP_OPTS"
      value: "-Xmx6g -Xms6g -XX:MaxDirectMemorySize=6g -XX:MetaspaceSize=96m"
    - name: "KAFKA_S3_ACCESS_KEY"
      value: "Replace With Your True ACCESS_KEY"
    - name: "KAFKA_S3_SECRET_KEY"
      value: "Replace With Your True SECRET_KEY"
externalAccess:
  controller:
    enabled: true
    service:
      type: LoadBalancer
      loadBalancerAnnotations:
        <Add Cloud Provider Specific Annotations Here>

      extraPorts:
        - name: "tcp-9092"
          port: 9092
          protocol: "TCP"
          targetPort: 9092
```

在上一步生成的配置文件中，部分参数需要根据实际情况进行替换。

#### 修改公共参数

**global.cloudProvider.name**

该参数约定了部署的云环境，请根据云厂商名称枚举值填写，如果是私有数据中心，也需要按照枚举值填充。

| **部署环境**<br />     | **参数枚举值**<br /> |
| ------------------ | --------------- |
| AWS<br />          | aws<br />       |
| Google Cloud<br /> | gcp<br />       |
| Azure<br />        | azure<br />     |
| OCI<br />          | noop<br />      |
| 阿里云<br />          | aliyun<br />    |

**global.cloudProvider.credentials**

该参数约定了 AutoMQ 集群访问云资源时使用的公共 Credentials 参数。当前示例以 AccessKey 类型的静态 Credentials 为例，如果期望使用 IAM Role 方式请参照高阶参数文档描述修改。

```yaml theme={null}

global:
  cloudProvider: 
    credentials: static://?accessKey=<your-accesskey>&secretKey=<your-secretkey>


```

**KAFKA\_S3\_ACCESS\_KEY 和 KAFKA\_S3\_SECRET\_KEY 环境变量**

示例的配置文件使用了 AccessKey 类型的静态 Credentials ，因此，除了 global.cloudProvider.credentials 参数，还需要将 Controller、Broker 的环境变量替换为正确的 Credentials。

参考 Step1 创建的 Credentials，将示例中的 Credentials 进行替换：

```yaml theme={null}

controller:
  env:
    - name: "KAFKA_S3_ACCESS_KEY"
      value: "Replace With Your True ACCESS_KEY"
    - name: "KAFKA_S3_SECRET_KEY"
      value: "Replace With Your True SECRET_KEY"

broker:
  env:
    - name: "KAFKA_S3_ACCESS_KEY"
      value: "Replace With Your True ACCESS_KEY"
    - name: "KAFKA_S3_SECRET_KEY"
      value: "Replace With Your True SECRET_KEY"

```

**global.config**

该参数约定了访问对象存储的 S3URL 配置，其中包括三个部分，分别是s3.ops.buckets、s3.data.buckets 以及 s3.wal.path。

<Tip>
  下方是使用 S3WAL 模式、静态 Credentials 的示例配置，如果您需要使用 EBSWAL 模式，请参考高阶配置章节的说明进行修改。
</Tip>

<Tabs>
  <Tab title="AWS">
    根据实际情况填充前置条件中创建的 Ops Bucket 和 Data Bucket。

    ```yaml theme={null}

    config: |
      s3.data.buckets=0@s3://<your-data-bucket>?region=xxxx&endpoint=https://s3.xxxx.amazonaws.com&authType=static
      s3.ops.buckets=1@s3://<your-ops-bucket>?region=xxxx&endpoint=https://s3.xxxx.amazonaws.com&authType=static
      s3.wal.path=0@s3://<your-data-bucket>?region=xxxx&endpoint=https://s3.xxxx.amazonaws.com&authType=static

    ```
  </Tab>

  <Tab title="Azure">
    根据实际情况填充 Ops Bucket、Data Bucket、region 以及 Endpoint 参数。

    ```yaml theme={null}

    config: |
      s3.data.buckets=0@s3://<your-data-bucket>?region=xxxx&endpoint=https://xxx_storage-account.blob.core.windows.net&authType=static
      s3.ops.buckets=1@s3://<your-ops-bucket>?region=xxxx&endpoint=https://xxx_storage-account.blob.core.windows.net&authType=static
      s3.wal.path=1@s3://<your-data-bucket>?region=xxxx&endpoint=https://xxx_storage-account.blob.core.windows.net&authType=static

    ```
  </Tab>

  <Tab title="Google Cloud">
    因为 GCP 上不支持使用 AccessKey 类型的静态 Credentials。格式有所不同，需要填充 Ops Bucket、Data Bucket、region、Endpoint 以及 GCP ServiceAccount 参数。

    ```yaml theme={null}

    config: |
      s3.data.buckets=0@s3://<your-data-bucket>?region=xxxx&endpoint=https://xxx_storage-account.blob.core.windows.net&authType=instance&role=<role-id>
      s3.ops.buckets=1@s3://<your-ops-bucket>?region=xxxx&endpoint=https://xxx_storage-account.blob.core.windows.net&authType=instance&role=<role-id>
      s3.wal.path=1@s3://<your-data-bucket>?region=xxxx&endpoint=https://xxx_storage-account.blob.core.windows.net&authType=instance&role=<role-id>

    ```
  </Tab>

  <Tab title="OCI">
    根据实际情况填充 Ops Bucket、Data Bucket、region 以及 Endpoint 参数。

    ```yaml theme={null}

    config: |
      s3.data.buckets=0@s3://<your-data-bucket>?region=xxxx&endpoint=https://xxx.compat.objectstorage.us-ashburn-1.oraclecloud.com&authType=static&pathStyle=true
      s3.ops.buckets=1@s3://<your-ops-bucket>?region=xxxx&endpoint=https://xxx.compat.objectstorage.us-ashburn-1.oraclecloud.com&authType=static&pathStyle=true
      s3.wal.path=0@s3://<your-data-bucket>?region=xxxx&endpoint=https://xxx.compat.objectstorage.us-ashburn-1.oraclecloud.com&authType=static&pathStyle=true

    ```
  </Tab>

  <Tab title="阿里云">
    根据实际情况填充 Ops Bucket、Data Bucket、region 以及 Endpoint 参数。

    ```yaml theme={null}

    config: |
      s3.data.buckets=0@s3://<your-data-bucket>?region=xxxx&endpoint=https://oss-cn-xxxx.aliyuncs.com&authType=static
      s3.ops.buckets=1@s3://<your-ops-bucket>?region=xxxx&endpoint=https://oss-cn-xxxx.aliyuncs.com&authType=static
      s3.wal.path=1@s3://<your-data-bucket>?region=xxxx&endpoint=https://oss-cn-xxxx.aliyuncs.com&authType=static

    ```
  </Tab>
</Tabs>

#### 修改存储类等参数

**controller.persistence.metadata.storageClass**

根据实际情况，将该参数替换成步骤 2 中创建的 Storage Class 名称，用于设置 AutoMQ Controller Pod 存储元数据。

#### 修改集群拓扑和资源 Request 参数

根据实际为 AutoMQ 分配的 Node 资源，调整集群拓扑和资源 Request 参数。需要修改的参数如下：

**broker.replicas**

AutoMQ Software Chart 默认会启动三个 Controller Pod，Controller Pod 同时也可以提供数据读写能力，如果用户期望额外水平扩展更多的 Broker，则可以设置 broker.replicas 参数。

* 默认值：0，代表三节点集群，不需要额外的 Broker。

* 设置范围：>= 0，按需配置。

**资源 Request 参数**

AutoMQ Software Controller 和 Broker 的 Pod 需要调整 Request 和 Limit 参数以及相应的 JVM HEAP 参数。上述配置文件中默认按 4Core16GB 规格配置，请根据实际分配的计算资源按需调整以下参数。

* controller.resources.requests.cpu

* controller.resources.requests.memory

* controller.resources.limits.cpu

* controller.resources.limits.memory

* controller.env.\[KAFKA\_HEAP\_OPTS]

* broker.resources.requests.cpu

* broker.resources.requests.memory

* broker.resources.limits.cpu

* broker.resources.limits.memory

* broker.env.\[KAFKA\_HEAP\_OPTS]

#### 设置 LoadBalancer 注解，开启 Kubernetes 集群外访问

如果需要从 Kubernetes 集群外部访问 AutoMQ，您需要启用 `externalAccess`。为了配置一个**内网 LoadBalancer**，您需要修改 `values.yaml` 中 `externalAccess.controller.service.loadBalancerAnnotations` 部分，并根据您的云厂商添加以下注解：

<Tabs>
  <Tab title="AWS">
    为创建一个内部网络负载均衡器 (NLB)，请添加以下注解：

    ```yaml theme={null}
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
    service.beta.kubernetes.io/aws-load-balancer-scheme: "internal"
    service.beta.kubernetes.io/aws-load-balancer-subnets: "subnet-xxxx,subnet-yyyy"
    ```
  </Tab>

  <Tab title="Azure">
    为创建一个内部标准 Load Balancer，请添加以下注解：

    ```yaml theme={null}
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    service.beta.kubernetes.io/azure-load-balancer-internal-subnet: "your-subnet-name"
    ```
  </Tab>

  <Tab title="GCP">
    为创建一个内部 TCP/UDP Load Balancer，请添加以下注解：

    ```yaml theme={null}
    networking.gke.io/load-balancer-type: "Internal"
    cloud.google.com/load-balancer-subnet: "your-subnet-name"
    ```
  </Tab>

  <Tab title="OCI">
    为创建一个内部 Load Balancer，请添加以下注解：

    ```yaml theme={null}
    oci.oraclecloud.com/load-balancer-type: "nlb"
    oci-network-load-balancer.oraclecloud.com/internal: "true"
    oci-network-load-balancer.oraclecloud.com/subnet: "<Replace With Your True Subnet OCID>"

    ```
  </Tab>
</Tabs>

### Step4： 安装 Chart 并访问集群

#### 安装集群

根据实际部署需求调整好 values.yaml 配置文件后，即可安装 AutoMQ。

```bash theme={null}

helm upgrade --install <release-name> oci://automq.azurecr.io/helm/automq-enterprise-chart --version 5.3.4 -f <your-custom-values.yaml> --namespace <namespace> --create-namespace 

```

安装完成后，用户即可在 Kubernetes 集群内访问 AutoMQ，可通过Headless service或者LoadBalancer进行访问 AutoMQ。

#### 通过 Headless service 在 Kubernetes 集群内访问 AutoMQ

1. **查找Headless service**

```bash theme={null}

kubectl get svc --namespace <namespace> -l "app.kubernetes.io/component=controller" -w

```

2. **使用Kafka客户端进行连接和测试**

Headless Service用作你的 Kafka 客户端的  `--bootstrap-server` 进行收发消息，可使用以下命令：

```bash theme={null}

./kafka-console-producer.sh \
  --bootstrap-server <release-name>-automq-enterprise-controller-0.<release-name>-automq-enterprise-controller-headless.<namespace>.svc.cluster.local:9092 \
  --topic test-topic

```

#### 通过 LoadBalancer 在 Kubernetes 集群外访问 AutoMQ

1. **查找 External Address**

等待 EXTERNAL-IP（外部 IP）分配完成。使用的下方命令可以获取到LoadBalancer的 external IP。

```bash theme={null}

kubectl get svc automq-release-automq-enterprise-controller-loadbalancer -n automq -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'

```

2. **使用Kafka客户端进行连接和测试**

Port  `9092`  被用作client的访问

```bash theme={null}

# Replace <EXTERNAL-IP> with the address from the previous step
./kafka-console-producer.sh \
  --bootstrap-server <EXTERNAL-IP>:9092 \
  --topic test-topic

```

<Tip>
  本章节仅展示了一个简易功能场景的集群部署流程。AutoMQ 团队同时提供了包括 TLS、认证授权、Auto-Scaler 等多种高阶功能示例，详情请参考[高阶功能示例 ▸](https://github.com/AutoMQ/automq-labs/tree/main/software-examples/kubernetes/)。
</Tip>

## 其他高阶配置

上述部署文档演示了 AutoMQ 使用 S3WAL 模式部署的简单示例，在实际生产场景中用户可以选择 EBSWAL、添加 Auto-Scaler 支持等高阶配置。完整的配置文件参考 [Helm Chart Values 文档▸](/zh/automq-cloud/appendix/helm-chart-values-readme)。

### 设置 WAL 类型

上述安装步骤中使用 S3WAL 作为示例，AutoMQ 同时支持 EBSWAL 和S3WAL两种部署方式。

<Tabs>
  <Tab title="S3WAL 模式">
    S3WAL 模式下，无需挂载 WAL 数据卷，配置相对简单，首先配置 global.config.s3.wal.path 参数。

    ```yaml theme={null}

    config: |  
      s3.wal.path=0@s3://<xxx-data-bucket>?region=<region>&endpoint=<endpoint>&authType=<authType>

    ```

    然后关闭 controller.persistence.wal.enabled 和  broker.persistence.wal.enabled 。

    ```yaml theme={null}

    # Applying StorageClass in controller/broker  
    controller:  
      persistence:  
        metadata:  
          storageClass: "your-storage-class"  
        wal:
          enabled: false
    broker:  
      persistence:
        wal:
          enabled: false


    ```
  </Tab>

  <Tab title="EBSWAL 模式">
    EBSWAL 模式下每个 controller 和 broker 都需要挂载 WAL 数据卷。因此需要设置 controller.persistence.wal.storageClass 和  broker.persistence.wal.storageClass，确保参数值设置为之前创建的 Storage Class。

    ```yaml theme={null}

    # Applying StorageClass in controller/broker  
    controller:  
      persistence:  
        metadata:  
          storageClass: "your-storage-class"  
        wal:  
          storageClass: "your-storage-class"
    broker:  
      persistence:  
        wal:  
          storageClass: "your-storage-class"


    ```

    然后，配置 global.config.s3.wal.path 参数。

    ```yaml theme={null}

    config: |  
      s3.wal.path=0@block:///dev/waliobandwidth=131072000&iodepth=8&iops=3000&capacity=2147483648

    ```
  </Tab>
</Tabs>

### 设置 Credentials

AutoMQ 同时支持使用静态的 AccessKey 或者动态 IAM Role 访问外部资源。生产环境中为防止静态的 AccessKey 配置泄露，更加推荐使用云厂商提供的 IAM Role 动态 Credentials。

<Tabs>
  <Tab title="IAM Role Credentials">
    使用 IAM Role Credentials 则需要在 Step1 中将授权策略附加给 Role。然后参考下方示例修改 Credentials 配置。

    ```yaml theme={null}

    global:
      cloudProvider: 
        credentials: instance://?role=<your-instance-profile>

      config: |
        s3.data.buckets=0@s3://<your-bucket>?authType=instance&role=<role-id>
        s3.ops.buckets=1@s3://<your-bucket>?authType=instance&role=<role-id>

    ```

    其中 credentials 的格式填写格式参考如下表格\*\*：\*\*

    | **部署环境**<br />     | **参数枚举值**<br />                                                                                            |
    | ------------------ | ---------------------------------------------------------------------------------------------------------- |
    | AWS<br />          | instance://?role=\<your-instance-profile><br />Role 填写 IAM 实例配置文件，不是 Role ARN。<br />                       |
    | Google Cloud<br /> | instance://?role=\<your-service-account-name><br />Role 填写 GCP 的 ServiceAccount 名称。<br />                  |
    | Azure<br />        | instance://?role=\<your-managed-identity-client-id><br />Role 填写 Azure 的 Managed Identity Client ID。<br /> |
    | 阿里云<br />          | instance://?role=\<your-role-id><br />Role 填写阿里云的  RAM Role 名称。<br />                                      |
  </Tab>

  <Tab title="AccessKey Credentials">
    使用 AccessKey Credentials 则需要在 Step1 中将授权策略附加给子账号或者服务账号等主体。然后参考下方示例修改 Credentials 配置。其中 authType 设置为 static。

    ```yaml theme={null}

    global:
      cloudProvider: 
        credentials: static://?accessKey=<your-accesskey>&secretKey=<your-secretkey>

      config: |
        s3.data.buckets=0@s3://<your-bucket>?authType=static
        s3.ops.buckets=1@s3://<your-bucket>?authType=static

    ```

    使用静态 AccessKey Credentials 后，还需要根据云厂商环境都要求，在 Controller、Broker 的环境变量中配置 Credentials。

    ```yaml theme={null}

    controller:
      env:
        - name: "KAFKA_S3_ACCESS_KEY"
          value: "Replace With Your True ACCESS_KEY"
        - name: "KAFKA_S3_SECRET_KEY"
          value: "Replace With Your True SECRET_KEY"

    broker:
      env:
        - name: "KAFKA_S3_ACCESS_KEY"
          value: "Replace With Your True ACCESS_KEY"
        - name: "KAFKA_S3_SECRET_KEY"
          value: "Replace With Your True SECRET_KEY"

    ```

    <Tip>
      如果当前部署环境位于 Azure，还需要额外设置环境变量：AZURE\_TENANT\_ID 为当前的租户 ID（tenantId）。
    </Tip>
  </Tab>
</Tabs>

### 设置细粒度调度策略

在 Kubernetes 中，AutoMQ 的细粒度调度策略是通过 nodeAffinities 和 tolerations 实现的。建议用户根据其节点类型自定义标签匹配规则：

#### Tolerations

建议在 Kubernetes 节点组中添加一个污点，键为："dedicated"，运算符为："Equal"，值为："automq"，效果为："NoSchedule"。并在 global.tolerations 中配置相应的容忍规则，以调度 Pod：

```yaml theme={null}

global:  
  tolerations:  
  - key: "dedicated"  
    operator: "Equal"  
    value: "automq"  
    effect: "NoSchedule"  

```

#### Node Affinities

覆盖控制器/代理配置中的默认值以匹配节点标签（例如，node-type: automq-worker）：

```yaml theme={null}

controller:  
  nodeAffinity:  
    requiredDuringSchedulingIgnoredDuringExecution:  
      nodeSelectorTerms:  
      - matchExpressions:  
        - key: "node-type"  
          operator: In  
          values: ["automq-worker"]  

```

### 设置弹性伸缩

#### Controller 数量

集群默认部署 3 个 Controller Pod，用户可自定义 Controller 副本数量。

<Danger>
  注意：集群部署完成后，暂不支持调整 Controller 的 Replicas，以免出现预期外的风险。
</Danger>

### Broker 数量

Broker 数量通过 broker.replicas 参数控制，可以水平扩展。默认为 0 个。

### Auto-scaling 配置

默认情况下，HPA（Horizontal Pod Autoscaler）是禁用的。要启用它，必须满足两个条件：

* broker.replicas > 0

* 在 global.autoscaling.hpa 中启用并配置参数：

```yaml theme={null}

global:  
  autoscaling:  
    hpa:  
      enabled: true        # Enable HPA  
      minReplicas: "1"     # Minimum replicas  
      maxReplicas: "3"     # Maximum replicas  
      targetCPU: "60"      # Target CPU utilization (%)  
      targetMemory: ""     # Target memory utilization (%) (optional)  

```

### 身份识别配置

AutoMQ 支持覆盖协议监听并启用安全认证，默认情况下会暴露以下端口：

* 客户端访问服务端：9092（PLAINTEXT）。
* Controller 间内部通信：9093（PLAINTEXT）。
* Broker 间内部通信：9094（PLAINTEXT）。

AutoMQ 还通过监听器配置（例如，启用 SASL 认证）覆盖自定义端口和协议来启用安全认证（允许的值有 'PLAINTEXT'、'SASL\_PLAINTEXT'、'SASL\_SSL' 和 'SSL'）。

```yaml theme={null}
listeners:
  client:
    - containerPort: 9092
      protocol: SASL_PLAINTEXT
      name: BROKER_SASL
  controller:
    - containerPort: 9093
      protocol: SASL_PLAINTEXT
      name: CONTROLLER_SASL
  interbroker:
    - containerPort: 9094
      protocol: SASL_PLAINTEXT
      name: BROKER_SASL
```

<Tip>
  同时你可以为其设置密码，默认随机生成
</Tip>

```yaml theme={null}
sasl:
  controller:
    user: "user1"
    password: "PWDxxx"
  interbroker:
    user: "user2"
    password: "PWDxxx"
  client:
    user: "user3"
    password: "PWDxxx"
```

#### （可选）结合 external-dns 自动写入 Route 53 记录

如果希望在 AWS 中自动把 NLB Hostname 绑定到私有域名，可按以下步骤启用 external-dns：

1. 在集群中安装 [external-dns](https://github.com/kubernetes-sigs/external-dns)，启动参数需包含 `--source=service --provider=aws --policy=upsert-only --registry=txt`，并通过 IRSA 或其它方式为其 ServiceAccount 提供 `route53:ListHostedZones`、`route53:ListResourceRecordSets`、`route53:ChangeResourceRecordSets` 权限。
2. `listeners.client[].advertisedHostnames.baseDomain` 必须与 Route 53 Hosted Zone 完全一致（例如 `automq.private`），`listeners.client[].advertisedHostnames.externalDns.privateZoneId` 以及 `externalAccess.controller.externalDns.privateZoneId` 也需指向同一个 Hosted Zone ID。
3. 在 `values.yaml` 中确认/追加如下配置，由监听器声明要发布的 FQDN，controller Service 负责暴露 NLB 并被 external-dns 监听：

```yaml theme={null}
listeners:
  client:
    - name: CLIENT_SASL_SSL
      containerPort: 9112
      protocol: SASL_SSL
      advertisedHostnames:
        enabled: true
        baseDomain: automq.private
        externalDns:
          privateZoneId: <your-route53-zone-id>

externalAccess:
  controller:
    enabled: true
    service:
      type: LoadBalancer
    externalDns:
      enabled: true
      hostname: automq-bootstrap.automq.private
      privateZoneId: <your-route53-zone-id>
      recordType: A
      ttl: 60
```

当 controller 的 Service 获得 `status.loadBalancer.ingress` 后，external-dns 会在该 Hosted Zone 内创建/更新 `automq-bootstrap.automq.private`。若要保留手动维护 DNS 的流程，只需把 `externalAccess.controller.externalDns.enabled` 设为 `false` 并手动创建记录。

### 配置 Prometheus RemoteWrite 指标集成

AutoMQ Server 支持通过 Prometheus RemoteWrite 协议将集群的指标数据直接推送到用户自定义的 Prometheus 实例中。这种方式无需在 Kubernetes 集群中额外部署 Prometheus 采集组件，简化了监控架构。

在 `values.yaml` 的 `global.config` 中配置 `s3.telemetry.metrics.exporter.uri` 参数即可启用该功能。根据 Prometheus 端点的鉴权方式，选择对应的配置格式：

<Tabs>
  <Tab title="无鉴权">
    不需要认证的 Prometheus 端点：

    ```yaml theme={null}
    global:
      config: |
        s3.telemetry.metrics.exporter.uri=rw://?endpoint=<your-prometheus-endpoint>
    ```
  </Tab>

  <Tab title="Basic Auth">
    使用用户名和密码进行基础认证：

    ```yaml theme={null}
    global:
      config: |
        s3.telemetry.metrics.exporter.uri=rw://?endpoint=<your-prometheus-endpoint>&auth=basic&username=<your-prometheus-username>&password=<your-prometheus-password>
    ```
  </Tab>

  <Tab title="Bearer Token">
    使用 Bearer Token 进行认证：

    ```yaml theme={null}
    global:
      config: |
        s3.telemetry.metrics.exporter.uri=rw://?endpoint=<your-prometheus-endpoint>&auth=bearer&token=<your-prometheus-token>
    ```
  </Tab>

  <Tab title="AWS SigV4">
    使用 AWS SigV4 签名认证（适用于 Amazon Managed Prometheus 等服务）：

    ```yaml theme={null}
    global:
      config: |
        s3.telemetry.metrics.exporter.uri=rw://?endpoint=<your-prometheus-endpoint>&auth=sigv4&region=<your-prometheus-region>
    ```
  </Tab>
</Tabs>

<Tip>
  启用 RemoteWrite 后，AutoMQ 会自动将 Broker 和 Controller 的核心指标推送到指定的 Prometheus 端点。关于指标监控和报警配置的详细说明，请参考 [Prometheus 监控&报警](/zh/automq-cloud/monitoring-alert/monitoring-alert-via-prometheus)。
</Tip>

## 安全与访问控制

AutoMQ 支持多种安全配置来保护传输中的数据和控制客户端访问。本节介绍两种通过 Helm Chart 部署时的主要客户端认证安全模型：`SASL_SSL` 和 `SSL` (双向 TLS)。

这两条路径是相互独立的，请选择符合您组织安全策略的路径。

<Tip>
  最新版 Helm Chart 只需要 **一份** TLS Secret（包含 `ca.crt`、`tls.crt`、`tls.key`）。AutoMQ 会自动复用这套证书给所有监听器以及内部客户端（AutoBalancer、管理员等），无需再准备额外的客户端证书；在 mTLS 场景下也会自动关闭这些内部客户端的主机名校验，以便它们通过 Pod IP 访问。
</Tip>

<Note>
  `tls.keystorePassword` 和 `tls.truststorePassword` 仅在使用 JKS/PKCS12 keystore 时需要。在默认的 PEM 模式下，Chart 会直接挂载 `kafka.crt`/`kafka.key`（或 `tls.crt`/`tls.key`）并供 Kafka 使用，这两个参数可以留空；如果你的私钥本身带有口令，可通过 `tls.keyPassword` 或相关 Secret 进行配置。
</Note>

***

### 路径一：配置 SASL\_SSL 认证

这是一种常见的安全模型，客户端使用“用户名+密码”进行认证，并且通信信道由 TLS 加密。

#### 步骤一：为 SASL\_SSL 配置 `values.yaml`

您需要定义一个 `SASL_SSL` 监听器，启用 ACL，并配置 SASL 用户及其密码。服务端会向客户端提供 TLS 证书，但客户端无需提供自己的证书来进行认证。

**`values.yaml` 配置示例：**

```yaml theme={null}
# 1. 为 SASL_SSL 客户端定义监听器
listeners:
  client:
    - containerPort: 9112
      protocol: SASL_SSL
      name: CLIENT_SASL_SSL
      advertisedHostnames:
        enabled: true
        baseDomain: automq.private
        externalDns:
          privateZoneId: <your-route53-zone-id>

# 2. 引用包含服务器 TLS 证书的 Secret
tls:
  type: PEM
  existingSecret: automq-server-tls # Secret 中必须包含 server.crt, server.key, ca.crt

# 3. 从外部暴露 SASL_SSL 端口
externalAccess:
  controller:
    enabled: true
    service:
      type: LoadBalancer
      extraPorts:
        - name: "sasl-client"
          port: 9112
          protocol: "TCP"
          targetPort: 9112
    externalDns:
      enabled: true
      hostname: automq-bootstrap.automq.private
      privateZoneId: <your-route53-zone-id>
      recordType: A
      ttl: 60

# 4. 启用 ACL 并定义 SASL 超级用户
acl:
  enabled: true
  superUsers:
    - "_automq"

# 5. 为超级用户和普通客户端用户定义凭证
sasl:
  controller:
    password: "\<strong-password-for-automq\>"
    user: _automq
  interbroker:
    password: "\<strong-password-for-automq\>"
    user: _automq
  client:
    users:
      - "my-user" # 一个普通的应用用户
    passwords:
      - "<password-for-my-user>"
```

#### 步骤二：部署后的 ACL 管理

部署集群后，您必须使用超级用户 (`_automq`) 为普通用户（如 `my-user`）授予权限。

1. **配置管理员客户端 (`superuser.properties`):**
   此文件允许您通过 `_automq` 的身份认证来运行管理工具。
   ```properties theme={null}
   security.protocol=SASL_SSL
   ```

sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required
username="\_automq"
password="\<strong-password-for-automq>";

# 客户端需要信任服务端的证书

ssl.truststore.certificates=/path/to/your/ca.crt

````

2.  **授予权限:**
使用 `kafka-acls.sh` 和管理员配置为 `my-user` 授予 `WRITE` 和 `READ` 权限。
```bash
kafka-acls.sh --bootstrap-server <your-load-balancer-dns>:9112 
  --command-config superuser.properties 
  --add --allow-principal User:my-user --operation WRITE --topic my-topic
````

#### 步骤三：客户端配置

一个普通的应用客户端 (`my-user`) 将使用以下配置来连接、生产和消费消息。

**使用 PEM 信任库的示例：**

```properties theme={null}
# 'my-user' 的 client.properties
security.protocol=SASL_SSL
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required 
  username="my-user" 
  password="<password-for-my-user>";

# 指向包含 CA 证书的 PEM 文件路径
ssl.truststore.certificates=/path/to/your/ca.crt
```

**使用 JKS 信任库的示例：**

```properties theme={null}
# 'my-user' 的 client.properties
security.protocol=SASL_SSL
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required 
  username="my-user" 
  password="<password-for-my-user>";

ssl.truststore.location=/path/to/your/truststore.jks
ssl.truststore.password=your_truststore_password
```

***

### 路径二：配置 SSL (mTLS) 认证

在此模型中，客户端通过提供一个受集群信任的 TLS 证书来进行身份验证，这被称为双向 TLS (mTLS)。

#### 步骤一：准备证书

您将需要一个证书体系：

* **服务端证书:** 用于 AutoMQ Broker。
* **管理员客户端证书:** 一个具有特定通用名称（例如 `CN=automq-admin`）的证书，供被指定为超级用户的管理员使用。
* **应用客户端证书:** 每个客户端应用都应有其唯一的证书（例如 `CN=my-app`）。

#### 步骤二：为 mTLS 配置 `values.yaml`

您需要定义一个 `SSL` 监听器，要求客户端进行身份验证，并将管理员证书的 Principal 设置为超级用户。

**`values.yaml` 配置示例：**

```yaml theme={null}
# 1. 为 mTLS 客户端定义监听器并要求客户端认证
listeners:
  client:
    - containerPort: 9122
      protocol: SSL
      name: CLIENT_MTLS
      # 此项强制启用 mTLS
      sslClientAuth: required
      advertisedHostnames:
        enabled: true
        baseDomain: automq.private
        externalDns:
          privateZoneId: <your-route53-zone-id>

# 2. 引用包含服务器 TLS 证书的 Secret
tls:
  type: PEM
  existingSecret: automq-server-tls

# 3. 从外部暴露 SSL 端口
externalAccess:
  controller:
    enabled: true
    service:
      type: LoadBalancer
      extraPorts:
        - name: "tls-client"
          port: 9122
          protocol: "TCP"
          targetPort: 9122
    externalDns:
      enabled: true
      hostname: automq-bootstrap.automq.private
      privateZoneId: <your-route53-zone-id>
      recordType: A
      ttl: 60

# 4. 启用 ACL 并定义基于证书的超级用户
acl:
  enabled: true
  # Principal 是 'User:' + 管理员证书的完整主题
  superUsers:
    - "User:CN=automq-admin"

# 5. SASL 仍用于内部通信
sasl:
  # ... _automq 的配置 ...
```

#### 步骤三：部署后的 ACL 管理

部署后，使用管理员证书为普通的应用 Principal 授予权限。

1. **配置管理员客户端 (`admin.properties`):**
   此文件使用管理员证书 (`CN=automq-admin`) 进行身份验证。

   **使用 PEM 文件 (推荐):**

   ```properties theme={null}
   security.protocol=SSL
   ssl.truststore.certificates=/path/to/your/ca.crt
   ssl.keystore.key=/path/to/your/admin.key
   ssl.keystore.certificate.chain=/path/to/your/admin.crt
   ```

   **使用 JKS 文件:**

   ```properties theme={null}
   security.protocol=SSL
   ssl.truststore.location=/path/to/your/truststore.jks
   ssl.truststore.password=your_truststore_password
   ssl.keystore.location=/path/to/your/admin-keystore.jks
   ssl.keystore.password=your_keystore_password
   ```

   **使用 JKS 文件:**

   ```properties theme={null}
   security.protocol=SSL
   ssl.truststore.location=/path/to/your/truststore.jks
   ssl.truststore.password=your_truststore_password
   ssl.keystore.location=/path/to/your/admin-keystore.jks
   ssl.keystore.password=your_keystore_password
   ```

2. **授予权限:**
   使用 `kafka-acls.sh` 为应用 Principal `User:CN=my-app` 授予权限。
   ```bash theme={null}
   kafka-acls.sh --bootstrap-server <your-load-balancer-dns>:9122 
     --command-config admin.properties 
     --add --allow-principal "User:CN=my-app" --operation WRITE --topic my-topic
   ```

#### 步骤四：客户端配置

一个普通的应用客户端将使用其自己唯一的证书 (`CN=my-app`) 进行连接。

**使用 PEM 文件 (推荐):**

```properties theme={null}
# 'my-app' 的 client.properties
security.protocol=SSL
ssl.truststore.certificates=/path/to/your/ca.crt
ssl.keystore.key=/path/to/your/myapp.key
ssl.keystore.certificate.chain=/path/to/your/myapp.crt
```

**使用 JKS 文件:**

```properties theme={null}
# 'my-app' 的 client.properties
security.protocol=SSL
ssl.truststore.location=/path/to/your/truststore.jks
ssl.truststore.password=your_truststore_password
ssl.keystore.location=/path/to/your/myapp-keystore.jks
ssl.keystore.password=your_keystore_password
```

## 性能调优

更多性能调优细节，请参考[AutoMQ 性能调优指南](https://docs.automq.com/automq/deployment/performance-tuning-for-broker)。
