Amazon MSKのマルチAZ設計入門|aws kafkaコマンドで実装するブローカー分散配置とVPCサブネット設計

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > AWS(Amazon Linux) > Amazon MSKのマルチAZ設計入門|aws kafkaコマンドで実装するブローカー分散配置とVPCサブネット設計
「MSKクラスターをシングルAZのサブネット1つに作ったまま本番稼働させていて、AZ障害で全ブローカーが落ちた」——この手の障害は設計ミスで起きます。Amazon MSKはブローカーを置くサブネットをユーザーが明示的に指定する仕様です。同じAZのサブネットを3つ渡せば、全ブローカーが同一AZに並びます。

実行環境:AWS リージョン ap-northeast-1(東京)、MSK Kafka バージョン 3.7.x で動作確認済み。

この記事では、Amazon MSKのブローカーを3つのAZに確実に分散させる設計手順を解説します。VPCサブネットの切り方・セキュリティグループのポート設定・aws kafka create-cluster-v2コマンドの実践・レプリケーション係数の決め方まで、本番投入前に確認すべき設計ポイントをひとつひとつ押さえます。

この記事のポイント

・MSKブローカーの分散配置はサブネット指定で決まる——AZが異なる3つのサブネットを必ず渡す
・aws kafka create-cluster-v2 の --broker-node-group-info でサブネットIDをAZバラバラに3つ指定する
・レプリケーション係数3+min.insync.replicas=2でAZ1つ消失してもデータ損失ゼロを実現できる
・ブローカーエンドポイントはTLSポート9094が推奨——sg設定とDNS疎通の確認で接続問題の大半は解消する


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜMSKのブローカーをマルチAZに分散するのか


Kafkaのパーティションは「リーダー」と「フォロワー」に分かれています。リーダーが置かれているブローカーのAZで障害が起きると、新しいリーダーが選出されるまでそのパーティションへの書き込みが止まります。ブローカーが全台同一AZにいれば、AZ障害でクラスター全体が機能停止します。

マルチAZ設計で得られる効果は次の2点です。

・AZ障害でのクラスター停止を防ぐ:1つのAZが落ちても残り2つのAZにブローカーが生き残り、フォロワーがリーダーに昇格してサービスを継続します
・データ損失ゼロを担保できる:レプリケーション係数を3に設定すると、3つのAZ全体にパーティションのコピーが保持されます。AWSのMSK SLAもマルチAZ構成を前提として可用性99.9%以上を保証しています

開発・検証環境でコスト削減のためシングルAZにするのは許容できますが、本番環境では必ずマルチAZ設計を採用してください。

MSKクラスターの構成要素と分散配置の仕組み


MSKのクラスターは以下の要素で構成されています。

・ブローカーノード:Kafkaブローカーが動くEC2インスタンス。クラスター作成時にVPCのサブネットIDを指定することで配置AZが決まる
・ZooKeeperノード(レガシー):KRaft(Kafka Raft)モードを選択するとZooKeeperは不要。新規クラスターはKRaftを推奨
・ブローカー数:最小2(開発用)、本番は3以上。AZ数と合わせるのが基本設計で、東京リージョン(ap-northeast-1)の3AZ構成なら3台または6台が一般的

MSKはサブネットIDをそのまま「ブローカーを置くAZ」として解釈します。たとえば次のようにサブネットを渡すと分散されます。

# 3つのAZのプライベートサブネットを指定——これがマルチAZ配置の核心 subnet-0aaa... # ap-northeast-1a subnet-0bbb... # ap-northeast-1c subnet-0ccc... # ap-northeast-1d

逆に同一AZのサブネットを3つ渡すと、全ブローカーが1つのAZに並びます。MSKはサブネットのAZを確認して分散しようとはしないため、ユーザー側で正しいサブネットを選ぶ責任があります。

VPCサブネット設計|3AZへのブローカー分散配置の準備


MSKのブローカーはインターネットに公開しないため、必ずプライベートサブネットに置きます。東京リージョンの3AZ(ap-northeast-1a、ap-northeast-1c、ap-northeast-1d)それぞれにプライベートサブネットを1つ用意するのが基本形です。

1. VPCとサブネットを作成する


まずVPC全体のCIDRを決めてサブネットを切り出します。MSK専用のサブネットを別に設けることで、ECS・EC2との混在を避けられます。

# VPC作成(例:10.0.0.0/16) $ aws ec2 create-vpc --cidr-block 10.0.0.0/16 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=msk-vpc}]' # MSK用プライベートサブネット——AZごとに1つずつ $ aws ec2 create-subnet --vpc-id vpc-0123456789abcdef0 --cidr-block 10.0.10.0/24 --availability-zone ap-northeast-1a --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=msk-private-1a}]' $ aws ec2 create-subnet --vpc-id vpc-0123456789abcdef0 --cidr-block 10.0.11.0/24 --availability-zone ap-northeast-1c --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=msk-private-1c}]' $ aws ec2 create-subnet --vpc-id vpc-0123456789abcdef0 --cidr-block 10.0.12.0/24 --availability-zone ap-northeast-1d --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=msk-private-1d}]'

2. セキュリティグループを設定する


MSKブローカーへのアクセスに必要なポートを開放します。不必要なポートは閉じることが重要です。

# MSK用セキュリティグループ作成 $ aws ec2 create-security-group --group-name msk-broker-sg --description "MSK Broker Security Group" --vpc-id vpc-0123456789abcdef0 # プレーンテキスト(非推奨。開発環境のみ) $ aws ec2 authorize-security-group-ingress --group-id sg-0msk123 --protocol tcp --port 9092 --source-group sg-0client456 # TLS接続(本番推奨) $ aws ec2 authorize-security-group-ingress --group-id sg-0msk123 --protocol tcp --port 9094 --source-group sg-0client456 # IAM認証+TLS $ aws ec2 authorize-security-group-ingress --group-id sg-0msk123 --protocol tcp --port 9098 --source-group sg-0client456 # KRaftモード(ZooKeeperなし)の場合は2181/2182は不要

ブローカーのポートが正しく開放されているかは、ECSタスクやEC2インスタンスから ss/lsof によるポート確認 で疎通チェックできます。

aws kafkaコマンドでMSKクラスターを作成する手順


VPCとサブネットの準備ができたら、いよいよMSKクラスターを作成します。aws kafka create-cluster-v2を使います。

1. クラスター設定JSONを用意する


コマンドラインが長くなるため、ブローカーノード設定をJSONファイルに分けると管理しやすくなります。

# broker-config.json { "BrokerAZDistribution": "DEFAULT", "ClientSubnets": [ "subnet-0aaa111222333444a", # ap-northeast-1a "subnet-0bbb111222333444b", # ap-northeast-1c "subnet-0ccc111222333444c" # ap-northeast-1d ], "InstanceType": "kafka.m5.large", "SecurityGroups": ["sg-0msk123abc456def"], "StorageInfo": { "EbsStorageInfo": { "VolumeSize": 100 } } }

ClientSubnetsに渡す3つのサブネットIDが異なるAZを指すことを必ず確認してください。これがマルチAZ設計の要になります。

2. クラスターを作成する


$ aws kafka create-cluster-v2 --cluster-name msk-prod --provisioned --kafka-version "3.7.x" --number-of-broker-nodes 3 --broker-node-group-info file://broker-config.json --client-authentication '{"Sasl":{"Iam":{"Enabled":true}},"Unauthenticated":{"Enabled":false}}' --encryption-info '{"EncryptionInTransit":{"ClientBroker":"TLS","InCluster":true}}' --region ap-northeast-1 { "ClusterArn": "arn:aws:kafka:ap-northeast-1:123456789012:cluster/msk-prod/abc123...", "ClusterName": "msk-prod", "State": "CREATING" }

3. クラスターの作成状態を確認する


クラスター作成には通常15~30分かかります。describe-cluster-v2で状態を確認します。

$ aws kafka describe-cluster-v2 --cluster-arn "arn:aws:kafka:ap-northeast-1:123456789012:cluster/msk-prod/abc123..." --region ap-northeast-1 --query "ClusterInfo.State" "ACTIVE" # ブローカーのエンドポイントを取得する $ aws kafka get-bootstrap-brokers --cluster-arn "arn:aws:kafka:ap-northeast-1:123456789012:cluster/msk-prod/abc123..." --region ap-northeast-1 { "BootstrapBrokerStringTls": "b-1.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com:9094,b-2.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com:9094,b-3.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com:9094", "BootstrapBrokerStringSaslIam": "b-1.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com:9098,b-2.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com:9098,b-3.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com:9098" }

BootstrapBrokerStringTlsに3つのホスト名(b-1、b-2、b-3)が含まれていれば、それぞれが別AZのブローカーを指しています。

ブローカーのエンドポイントはAmazonが発行するDNS名で提供されます。VPC内からこのDNS名を正しく解決できることを確認してください。DNS名前解決のトラブルが発生した場合はLinux DNS 設定の基本を参照すると、VPC内のDNS解決設定を見直すヒントが得られます。

レプリケーション設定とISR|AZ障害時のデータ損失ゼロを実現する


MSKクラスターのブローカーを3AZに分散しただけでは不十分です。トピックのレプリケーション係数と、プロデューサーの応答条件を正しく設定することで、初めてデータ損失ゼロが担保されます。

1. トピックのレプリケーション係数を3に設定する


# kafka-topicsコマンドでトピックを作成(EC2またはECSクライアントから実行) $ kafka-topics.sh --bootstrap-server b-1.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com:9098 --command-config client.properties --create --topic app-events --partitions 12 --replication-factor 3 Created topic app-events. # レプリカの配置を確認する $ kafka-topics.sh --bootstrap-server b-1.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com:9098 --command-config client.properties --describe --topic app-events Topic: app-events PartitionCount: 12 ReplicationFactor: 3 Topic: app-events Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3 Topic: app-events Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1 Topic: app-events Partition: 2 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2

Isr(In-Sync Replicas)の数が3のままであれば、全てのレプリカが同期状態です。

2. min.insync.replicasとプロデューサーのacksを設定する


レプリケーション係数3だけでは、プロデューサーがリーダーへの書き込み完了だけで「成功」とみなす設定になっています(acks=1のデフォルト)。これではリーダーへの書き込み後にAZ障害が起きると、フォロワーへの複製前にメッセージが失われます。

・min.insync.replicas = 2:トピック設定でブローカーが「成功」と判断するために必要な同期レプリカ数を2に設定
・acks = all(または -1):プロデューサー設定で、全同期レプリカへの書き込み完了を待つよう設定

この組み合わせで「AZが1つ落ちて同期レプリカが2台になっても書き込みは継続する、かつ残り2台への複製が完了するまでプロデューサーに成功を返さない」動作になります。

MSKのAWSマネジメントコンソールまたはCLIからMSKのクラスター設定を変更することでmin.insync.replicasをデフォルト値から変更できます。AWSのマルチAZ冗長設計全体については、AWSマスターセミナー上級編でより体系的に学べます。

MSKブローカーへの接続確認と疎通テスト


クラスターがACTIVEになったら、アプリケーションクライアント(ECSタスクやEC2)から接続できるかを確認します。

1. ブローカーエンドポイントのDNS解決を確認する


# クライアントEC2またはECSタスク内から実行 $ nslookup b-1.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com Server: 169.254.169.253 Address: 169.254.169.253#53 Non-authoritative answer: Name: b-1.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com Address: 10.0.10.45

返ってくるIPアドレスがMSKのプライベートサブネット(10.0.10.x、10.0.11.x、10.0.12.x)内に収まっていれば正常です。VPC外のIPアドレスが返る場合はVPCのDNS設定(enableDnsHostnames/enableDnsSupport)を確認してください。

2. IAM認証でのkafka-console-producerテスト


# client.properties(IAM認証設定) security.protocol=SASL_SSL sasl.mechanism=AWS_MSK_IAM sasl.jaas.config=software.amazon.msk.auth.iam.IAMLoginModule required; sasl.client.callback.handler.class=software.amazon.msk.auth.iam.IAMClientCallbackHandler # テストメッセージの送信 $ kafka-console-producer.sh --bootstrap-server b-1.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com:9098 --topic app-events --producer.config client.properties >test-message-1 >test-message-2

トラブルシュート|よくある構成ミスと確認コマンド


ブローカーに接続できない(Connection refused / Timeout)


原因のほとんどはセキュリティグループの設定漏れです。次の順で確認してください。

・クライアントのSGからMSKブローカーSGへのインバウンドルールが正しいポートで開放されているか(9094または9098)
・aws kafka get-bootstrap-brokersで取得したエンドポイントのポート番号と、クライアントの接続設定が一致しているか
・プロデューサーのsecurity.protocol設定が実際に有効なポートと合っているか(TLSなら9094、SAL_SSL+IAMなら9098)

Under-replicated partitions が発生している


ISRから外れたブローカーが存在するとunder-replicatedパーティションが増えます。

# under-replicated partitions を確認する $ kafka-topics.sh --bootstrap-server b-1.msk-prod.abc123.c2.kafka.ap-northeast-1.amazonaws.com:9098 --command-config client.properties --describe --under-replicated-partitions Topic: app-events Partition: 3 Leader: 2 Replicas: 2,3,1 Isr: 2,1 # Isr に 3 が含まれていない = ブローカー3番がISRから外れている

一時的なネットワーク遅延でもISRから外れることがあります。数分待ってから再確認してください。解消しない場合はCloudWatchのUnderReplicatedPartitionsメトリクスでアラートを設定し、長期的な傾向を監視します。

AZの偏りでコストが増大する(AZトラフィック課金)


プロデューサーが1つのAZのブローカーにのみ接続していると、AZをまたぐレプリケーショントラフィックが偏ります。ECS・EC2クライアントを全AZに均等配置し、ブローカーのDNSでAZローカルなブローカーへルーティングするMSK Rack Awarenessを有効にすることで、クロスAZトラフィックを削減できます。

本記事のまとめ


やりたいこと ポイント・コマンド
ブローカーを3AZに分散する --broker-node-group-info の ClientSubnets を異なるAZのサブネット3つで指定する
ブローカーエンドポイントを取得する aws kafka get-bootstrap-brokers --cluster-arn <ARN>
トピックのレプリケーション係数を設定する kafka-topics.sh --replication-factor 3
データ損失ゼロを担保する min.insync.replicas=2 + プロデューサー acks=all
under-replicatedパーティションを確認する kafka-topics.sh --under-replicated-partitions
クラスターの状態を確認する aws kafka describe-cluster-v2 --cluster-arn <ARN>

Amazon MSKのマルチAZ設計では「サブネット指定でAZ分散を保証する」「レプリケーション係数とacks設定でデータ損失ゼロを担保する」の2軸が核心です。これらを正しく設定した上で、CloudWatchによるISR監視とSGの最小権限設計を組み合わせることで、本番品質のKafka基盤を構築できます。

Linuxを活かしてAWSを使いこなしたい方には、Amazon Linux環境のセットアップ解説も参考にしてください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、LinuxMaster.JPではAWSをLinuxサーバーとして使いこなすための実践セミナーを開催しています。コマンドの丸暗記ではなく、設計の考え方と実機ハンズオンで「なぜそうするか」まで理解できるカリキュラムです。
>> AWSセミナーの詳細を見る

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。