<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ansible &#8211; SRA OSS Tech Blog</title>
	<atom:link href="https://www.sraoss.co.jp/tech-blog/tag/ansible/feed/index.xml" rel="self" type="application/rss+xml" />
	<link>https://www.sraoss.co.jp/tech-blog/</link>
	<description>OSS専門の技術ブログ。PostgreSQL、Zabbixを中心に10種類以上のOSSの解説、アップデート情報、運用ヒントを提供。</description>
	<lastBuildDate>Wed, 04 Nov 2026 06:54:38 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2018/07/blog-icon-150x150.png</url>
	<title>Ansible &#8211; SRA OSS Tech Blog</title>
	<link>https://www.sraoss.co.jp/tech-blog/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Ansible を用いた Kafka クラスターの構築</title>
		<link>https://www.sraoss.co.jp/tech-blog/kafka/ansible-kafka-cluster/</link>
		
		<dc:creator><![CDATA[奥井 一暁 (Kazuaki Okui)]]></dc:creator>
		<pubDate>Thu, 18 Sep 2025 00:00:14 +0000</pubDate>
				<category><![CDATA[Kafka]]></category>
		<category><![CDATA[Ansible]]></category>
		<category><![CDATA[Apache Kafka]]></category>
		<category><![CDATA[OSS]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=18515</guid>

					<description><![CDATA[はじめに 本記事では複数台のマシンを用いて Kafka クラスターを構築し、簡単な動作確認を行います。構築には Ansible を用いて、動作に必要な最低限の設定を行います。使用するバージョンは以下の通りです。 名前 バ ...]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">はじめに</h2>



<p class="wp-block-paragraph">本記事では複数台のマシンを用いて Kafka クラスターを構築し、簡単な動作確認を行います。構築には Ansible を用いて、動作に必要な最低限の設定を行います。使用するバージョンは以下の通りです。</p>
<p><span id="more-18515"></span></p>
<table class="code-line" dir="auto" data-line="21">
<thead class="code-line" dir="auto" data-line="22">
<tr class="code-line" dir="auto" data-line="22">
<th>名前</th>
<th>バージョン</th>
</tr>
</thead>
<tbody class="code-line" dir="auto" data-line="24">
<tr class="code-line" dir="auto" data-line="24">
<td>Rocky Linux</td>
<td>9.5</td>
</tr>
<tr class="code-line" dir="auto" data-line="25">
<td>Apache Kafka</td>
<td>4.0.0</td>
</tr>
<tr class="code-line" dir="auto" data-line="26">
<td>Ansible</td>
<td>2.15.13</td>
</tr>
</tbody>
</table>



<h2 class="wp-block-heading">Kafka について</h2>



<p class="wp-block-paragraph">Apache Kafka はストリーミング処理を実現するための OSS です。複数台のマシンで並列分散処理を行わせることができ、高いスケーラビリティ、障害耐性、低いレイテンシといった特徴があります。複数台のマシンでクラスターを構成するため、Ansible を使ってクラスター全体を構築すると楽です。</p>



<p class="wp-block-paragraph">簡単な動作確認ができる Docker 環境も用意されているのですが、ここでは各マシンに Kafka のバイナリを配置することから始めてクラスターを構築します。Docker 環境で Kafka の動作を試す方法については<a href="https://www.sraoss.co.jp/tech-blog/kafka/apache-kafka-entry/">こちら</a>の記事をご覧ください。</p>



<h2 class="wp-block-heading">Ansible について</h2>



<p class="wp-block-paragraph">Ansible はサーバ構築を自動化するための OSS です。サーバ構築をコード化できるので同時に構築するサーバ数を増やしたりインストールするパッケージを変更したりするのも容易です。コードを見ればサーバの仕様が分かるようにもなります。</p>



<p class="wp-block-paragraph">サーバ構築のコードを書く際、実行のたびにサーバーの状態が変わってしまうコードになることがあります。そのため何回実行してもサーバの状態が同じになる（このような性質を冪等性と言います）ように気を付ける必要があります。本記事でも冪等性を適宜確認しながら進めます。</p>



<h2 class="wp-block-heading">今回構築するクラスターの概要</h2>



<p class="wp-block-paragraph"><img fetchpriority="high" decoding="async" class="alignnone wp-image-18630" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2025/08/46f9da528f2535d7bef6a93902e07846-300x200.png" alt="" width="550" height="367" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2025/08/46f9da528f2535d7bef6a93902e07846-300x200.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2025/08/46f9da528f2535d7bef6a93902e07846-768x513.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2025/08/46f9da528f2535d7bef6a93902e07846-304x203.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2025/08/46f9da528f2535d7bef6a93902e07846-282x188.png 282w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2025/08/46f9da528f2535d7bef6a93902e07846.png 1000w" sizes="(max-width: 550px) 100vw, 550px" /></p>



<p class="wp-block-paragraph">本記事では Broker プロセスが合計5つ、Controller プロセスが合計3つのクラスターを構築します。これらを５台のマシン（Broker とController のプロセスを動かす kafka1~3＋Broker のみの kafka4, 5）で稼働させます。 加えてAnsible のコントロールマシンを立てて Kafka クラスター5台の操作を行います。</p>
<p>Ansible のコントロールマシンと Kafka クラスター5台は ssh で通信できるように設定しておきます。 また dnf によるパッケージインストール時など、root 権限を取得することがあるので構築対象サーバで Ansible を実行するユーザーには sudo 権限を与えておきます。</p>



<h2 class="wp-block-heading">Ansible ディレクトリ構造</h2>



<pre><code class="code-line code-active-line" dir="auto" data-line="57">$ tree
.
├── README
├── group_vars
│   └── kafka_cluster.yaml
├── host_vars
│   ├── kafka1.yaml
│   ├── kafka2.yaml
│   ├── kafka3.yaml
│   ├── kafka4.yaml
│   └── kafka5.yaml
├── inventory.ini
├── roles
│   ├── common
│   │   └── templates
│   │       └── kafka_service_template.j2
│   ├── java
│   │   └── tasks
│   │       └── main.yaml
│   ├── kafka_broker
│   │   ├── tasks
│   │   │   └── main.yaml
│   │   └── vars
│   │       └── main.yaml
│   ├── kafka_cluster
│   │   ├── files
│   │   │   └── kafka_2.13-4.0.0.tgz
│   │   └── tasks
│   │       └── main.yaml
│   ├── kafka_controller
│   │   ├── tasks
│   │   │   └── main.yaml
│   │   └── vars
│   │       └── main.yaml
│   ├── terminate_kafka_broker
│   │   └── tasks
│   │       └── main.yaml
│   └── terminate_kafka_controller
│       └── tasks
│           └── main.yaml
├── setup_servers.yaml
└── terminate_servers.yaml

20 directories, 20 files</code></pre>





<p class="wp-block-paragraph">今回、Kafka の環境準備から設定ファイルの編集、起動 までを行う Playbook（setup_servers.yaml）と Kafka の終了を行う Playbook（terminate_servers.yaml）を作成しました。</p>



<h2 class="wp-block-heading">playbook 全体の流れ</h2>



<p class="wp-block-paragraph">setup_servers.yaml を以下に示します。</p>



<pre><code class="code-line" dir="auto" data-line="109">- name: Setup kafka_broker_controller
  hosts: kafka_broker_controller 
  roles:
    - java
    - kafka_cluster
    - kafka_controller
    - kafka_broker

- name: Setup kafka_broker
  hosts: kafka_broker
  roles: 
    - java
    - kafka_cluster
    - kafka_broker</code></pre>





<p class="wp-block-paragraph">terminate_servers.yaml を以下に示します。</p>



<pre><code class="code-line" dir="auto" data-line="127">- name: Terminate kafka_broker
  hosts: kafka_broker
  roles: 
    - terminate_kafka_broker

- name: Terminate kafka_broker_controller
  hosts: kafka_broker_controller
  roles:  
    - terminate_kafka_broker
    - terminate_kafka_controller</code></pre>
<p class="code-line" dir="auto" data-line="139">各タスクは以下の通りです。</p>
<table class="code-line" dir="auto" data-line="141">
<thead class="code-line" dir="auto" data-line="141">
<tr class="code-line" dir="auto" data-line="141">
<th>name</th>
<th>説明</th>
</tr>
</thead>
<tbody class="code-line" dir="auto" data-line="143">
<tr class="code-line" dir="auto" data-line="143">
<td>Setup kafka_broker_controller</td>
<td>kafka1、kafka2、kafka3 で Broker と Controller のプロセスを起動</td>
</tr>
<tr class="code-line" dir="auto" data-line="144">
<td>Setup kafka_broker</td>
<td>kafka4、kafka5 で Broker プロセスを起動</td>
</tr>
<tr class="code-line" dir="auto" data-line="145">
<td>Terminate kafka_broker</td>
<td>kafka4、kafka5 の Broker プロセスを終了</td>
</tr>
<tr class="code-line" dir="auto" data-line="146">
<td>Terminate kafka_broker_controller</td>
<td>kafka1、kafka2、kafka3 の Broker と Controller のプロセスを終了</td>
</tr>
</tbody>
</table>
<p class="code-line code-active-line" dir="auto" data-line="149">各role は以下の通りです。</p>
<table class="code-line" dir="auto" data-line="151">
<thead class="code-line" dir="auto" data-line="151">
<tr class="code-line" dir="auto" data-line="151">
<th>role</th>
<th>説明</th>
</tr>
</thead>
<tbody class="code-line" dir="auto" data-line="153">
<tr class="code-line" dir="auto" data-line="153">
<td>java</td>
<td>Java のインストール</td>
</tr>
<tr class="code-line" dir="auto" data-line="154">
<td>kafka_cluster</td>
<td>Kafka クラスタ共通のタスク（Kafka バイナリの配布）</td>
</tr>
<tr class="code-line" dir="auto" data-line="155">
<td>kafka_controller</td>
<td>Controller の設定＋起動</td>
</tr>
<tr class="code-line" dir="auto" data-line="156">
<td>kafka_broker</td>
<td>Broker の設定＋起動</td>
</tr>
<tr class="code-line" dir="auto" data-line="157">
<td>terminate_kafka_broker</td>
<td>Broker の停止</td>
</tr>
<tr class="code-line" dir="auto" data-line="158">
<td>terminate_kafka_controller</td>
<td>Controller の停止</td>
</tr>
</tbody>
</table>
<p class="code-line" dir="auto" data-line="160">Controller プロセスは Broker プロセスより先に起動するようにしてあります。Broker プロセスの動作のためにはController が必要だからです。プロセスの終了では逆に Broker プロセスを先に終了させています。</p>
<p>&nbsp;</p>
<h2 class="wp-block-heading">Java のインストール</h2>



<p class="wp-block-paragraph">roles/java/task/main.yaml に Java のインストールを行うタスクを記載しています。</p>
<p>

</p>
<pre class="wp-block-code"><code>- name: Ensure openjdk21 present
  ansible.builtin.dnf:
    name: java-21-openjdk
    state: present
  become: true</code></pre>
<p>

</p>
<p class="wp-block-paragraph">ansible.builtin.dnf では name にパッケージ名、state に実行後どんな状態であるべきかを指定することでパッケージのインストール、アンインストールを行うことができます。state に指定できる状態は以下の通りです。</p>
<table class="code-line" dir="auto" data-line="163">
<thead class="code-line" dir="auto" data-line="163">
<tr class="code-line" dir="auto" data-line="163">
<th>設定値</th>
<th>説明</th>
</tr>
</thead>
<tbody class="code-line" dir="auto" data-line="165">
<tr class="code-line" dir="auto" data-line="165">
<td>present</td>
<td>パッケージがインストールされた状態にします。すでにインストールされている場合は何もしません。installed と同じです。</td>
</tr>
<tr class="code-line" dir="auto" data-line="166">
<td>latest</td>
<td>パッケージが最新版にアップデートされた状態にします。未インストールの場合はインストールします。</td>
</tr>
<tr class="code-line" dir="auto" data-line="167">
<td>absent</td>
<td>パッケージがアンインストールされた状態にします。removed と同じです。</td>
</tr>
</tbody>
</table>
<p>2回目以降の実行でバージョンが変わらないようにここでは present を使っています。</p>
<p>

</p>
<h2 class="wp-block-heading">Kafka バイナリの配置</h2>
<p>

</p>
<p class="wp-block-paragraph">roles/kafka_cluster/task/main.yaml に Kafka バイナリの配置を行うタスクを記載しています。</p>
<pre><code class="code-line" dir="auto" data-line="174">- name: Unarchive kafka file
  ansible.builtin.unarchive:
    src: ./roles/kafka_cluster/files/{{kafka_dir}}.tgz
    dest: '{{install_dir}}'
    creates: '{{install_dir}}/{{kafka_dir}}'</code></pre>
<p>

</p>
<p class="wp-block-paragraph">ansible.builtin.unarchive では src に Ansible 環境上のアーカイブファイル、dest に構築対象サーバの展開先ディレクトリを指定することでアーカイブファイルの展開ができます。このように設定するとアーカイブファイルを構築対象サーバに送信した後展開処理は構築対象サーバ上で行うという挙動になります。ここではあらかじめ ./roles/kafka_cluster/files/ に置いておいた kafka_2.13-4.0.0.tgz を各サーバで展開しています（変数 kafka_dir と install_dir は group_vars/kafka_cluster.yaml で定義しています）。</p>
<p>

</p>
<p class="wp-block-paragraph">構築対象サーバでアーカイブファイルのダウンロード、展開をさせるという方法も考えられます。どのような方法を採用するかは各環境によるでしょう。</p>
<p>

</p>
<p class="wp-block-paragraph">また creates に展開後ディレクトリのパスを指定すると、そのディレクトリがすでに存在する場合タスクをスキップさせることができます。<br />creates がない場合、2回目以降の実行で ansible.builtin.unarchive は展開後のファイルが変更されていないか確認し、変更があれば元の状態に戻すという動きをします。その動きで時間がかからないようにここでは creates を使っていますが、再展開させる必要がある場合は creates を削除するとよいでしょう。</p>
<p>

</p>
<h2 class="wp-block-heading">設定</h2>
<p>

</p>
<h3 class="wp-block-heading">Broker の設定</h3>
<p>

</p>
<p class="wp-block-paragraph">

</p>
<p class="wp-block-paragraph">roles/kafka_broker/task/main.yaml に Broker の設定を行うタスクを記載しています。</p>
<pre><code class="code-line" dir="auto" data-line="194">- name: Set node.id
  ansible.builtin.lineinfile:
    path: '{{path_to_properties}}'
    state: present
    regexp: '^node.id='
    line: node.id={{node_id_broker}}

- name: Unset controller.quorum.bootstrap.servers
  ansible.builtin.lineinfile:
    path: '{{path_to_properties}}'
    state: present
    regexp: '^controller.quorum.bootstrap.servers='
    line:  '# controller.quorum.bootstrap.servers='

- name: Set controller.quorum.voters 
  ansible.builtin.lineinfile:
    path: '{{path_to_properties}}'
    state: present
    regexp: '^#controller.quorum.voters='
    line:  'controller.quorum.voters=201@{{ hostvars["kafka1"].ansible_host }}:9093,202@{{ hostvars["kafka2"].ansible_host }}:9093,203@{{ hostvars["kafka3"].ansible_host }}:9093'

- name: Set listeners
  ansible.builtin.lineinfile:
    path: '{{path_to_properties}}'
    state: present
    regexp: '^listeners='
    line: listeners=PLAINTEXT://{{ansible_host}}:9092

- name: Unset advertised.listeners
  ansible.builtin.lineinfile:
    path: '{{path_to_properties}}'
    state: present
    regexp: '^advertised.listeners='
    line: '# advertised.listeners='</code></pre>
<p>

</p>
<p class="wp-block-paragraph">ansible.builtin.lineinfile では行の置き換えや挿入、削除ができます。ここでは path に指定したファイル内の regexp にマッチした行を line で指定した文字列で置き換えています。</p>
<p>

</p>
<p class="wp-block-paragraph">path に指定している path_to_properties ですが、roles/kafka_broker/vars/main.yaml にて kafka_2.13-4.0.0/configs/broker.properties になるように指定しています。つまり kafka_2.13-4.0.0.tgz に同梱されている Broker 用の設定ファイルから設定に必要な行を書き換えています。</p>
<p>

</p>
<p class="wp-block-paragraph">regexp にマッチする行がなかった場合は、line に指定した文字列と同じ内容の行があれば何もしない、なければファイル末尾に line の行を挿入するという挙動になります。そのため複数回実行しても同じ内容が挿入され続けることはなく、冪等性が保たれています。</p>
<p>

</p>
<p class="wp-block-paragraph">変更している設定値は以下の通りです。ここで Quorum について、静的 Quorum または動的 Quorum が使用できますが今回は静的 Quorum を採用しています。</p>
<p>&nbsp;</p>
<table class="code-line" dir="auto" data-line="239">
<thead class="code-line" dir="auto" data-line="239">
<tr class="code-line" dir="auto" data-line="239">
<th>設定値</th>
<th>説明</th>
</tr>
</thead>
<tbody class="code-line" dir="auto" data-line="241">
<tr class="code-line" dir="auto" data-line="241">
<td>node.id</td>
<td>各 Broker または Controller固有の ID で、被りがあってはいけません。変数 node_id_broker はホストごとに指定しています。</td>
</tr>
<tr class="code-line" dir="auto" data-line="242">
<td>controller.quorum.bootstrap.servers</td>
<td>動的 Quorum を採用する場合は、こちらの設定にすべての Controller を {host}:{port} の形でカンマ区切りで指定します。今回静的 Quorum なのでコメントアウトしています。</td>
</tr>
<tr class="code-line" dir="auto" data-line="243">
<td>controller.quorum.voters</td>
<td>静的 Quorum を採用する場合、こちらの設定にすべての Controller を {node.id}@{host}:{port} の形でカンマ区切りで指定します。</td>
</tr>
<tr class="code-line" dir="auto" data-line="244">
<td>listeners</td>
<td>接続を受け付けるリスナーを {リスナー名}://{host}:{port} で指定します。リスナー名ごとにセキュリティプロトコルが listener.security.protocol.map で指定でき、ここでは PLAINTEXT は認証や暗号化のないリスナーを表しています。</td>
</tr>
<tr class="code-line" dir="auto" data-line="245">
<td>advertised.listeners</td>
<td>Kafka クライアントからの接続に使うリスナーを指定します。これが設定されていなければ listeners の設定値が使われます。今回は同じで良いのでコメントアウトしています。</td>
</tr>
</tbody>
</table>
<p>

</p>
<p class="wp-block-paragraph">

</p>
<h3 class="wp-block-heading">Controller の設定</h3>
<p>

</p>
<p class="wp-block-paragraph">

</p>
<p class="wp-block-paragraph">roles/kafka_controller/task/main.yaml に Controller の設定を行うタスクを記載しています。</p>
<pre><code class="code-line" dir="auto" data-line="250">- name: Set node.id
  ansible.builtin.lineinfile:
    path: '{{path_to_properties}}'
    state: present
    regexp: '^node.id='
    line: node.id={{node_id_controller}}

- name: Unset controller.quorum.bootstrap.servers
  ansible.builtin.lineinfile:
    path: '{{path_to_properties}}'
    state: present
    regexp: '^controller.quorum.bootstrap.servers='
    line: '# controller.quorum.bootstrap.servers='

- name: Set controller.quorum.voters 
  ansible.builtin.lineinfile:
    path: '{{path_to_properties}}'
    state: present
    regexp: '^#controller.quorum.voters='
    line:  'controller.quorum.voters=201@{{ hostvars["kafka1"].ansible_host }}:9093,202@{{ hostvars["kafka2"].ansible_host }}:9093,203@{{ hostvars["kafka3"].ansible_host }}:9093'

- name: Set listeners
  ansible.builtin.lineinfile:
    path: '{{path_to_properties}}'
    state: present
    regexp: '^listeners='
    line: listeners=CONTROLLER://{{ansible_host}}:9093

- name: Unset advertised.listeners
  ansible.builtin.lineinfile:
    path: '{{path_to_properties}}'
    state: present
    regexp: '^advertised.listeners='
    line: '# advertised.listeners='</code></pre>
<p>

</p>
<p class="wp-block-paragraph">Controller 側の設定もほとんど同じですが、node_id は Controller 用、listeners はリスナー名が CONTROLLER、ポート番号が 9093 になっています。CONTROLLER も認証や暗号化のないリスナーを表しています。</p>
<p>

</p>
<h2 class="wp-block-heading">起動</h2>
<p>

</p>
<p>

</p>
<h3 class="wp-block-heading">ログディレクトリのフォーマット</h3>
<p>

</p>
<p class="wp-block-paragraph">

</p>
<p class="wp-block-paragraph">

</p>
<p class="wp-block-paragraph">roles/kafka_broker/task/main.yaml と roles/kafka_controller/task/main.yaml にログディレクトリのフォーマットを行うタスクを記載しています。内容は同じです。</p>
<pre><code class="code-line" dir="auto" data-line="293">- name: Format Log Directory
  ansible.builtin.shell:
    cmd: bin/kafka-storage.sh format -t {{kafka_cluster_id}} -c {{path_to_properties}} --ignore-formatted
    chdir: '{{install_dir}}/{{kafka_dir}}/'</code></pre>
<p>

</p>
<p class="wp-block-paragraph">ansible.builtin.shell は cmd に指定したコマンドを chdir で指定したディレクトリ上で実行します。コマンドをただ実行するだけのモジュールのため、冪等性の確保等は行いません。Kafka 起動前には Broker と Controller それぞれでログディレクトリのフォーマットが必要ですが、それは kafka_2.13-4.0.0.tgz の bin ディレクトリにある kafka-storage.sh を使って実行します。shell モジュールは冪等性の観点では避けるべきモジュールですが、kafka-storage.sh を使うために今回は使用しています。</p>
<p>

</p>
<p class="wp-block-paragraph">kafka-storage.sh format とすればフォーマットを行います。オプションは以下の通りです。</p>
<table class="code-line" dir="auto" data-line="305">
<thead class="code-line" dir="auto" data-line="305">
<tr class="code-line" dir="auto" data-line="305">
<th>オプション</th>
<th>説明</th>
</tr>
</thead>
<tbody class="code-line" dir="auto" data-line="307">
<tr class="code-line" dir="auto" data-line="307">
<td>-t {クラスターID}</td>
<td>クラスター全体で共通な ID を指定します。変数 kafka_cluster_id は group_vars/kafka_cluster.yaml でクラスター共通な変数として定義しています。</td>
</tr>
<tr class="code-line" dir="auto" data-line="308">
<td>-c {設定ファイル}</td>
<td>サーバの設定ファイルを指定します。</td>
</tr>
<tr class="code-line" dir="auto" data-line="309">
<td>&#8211;ignore-formatted</td>
<td>すでにフォーマットが済んでいた場合エラーにせず正常終了させます。このオプションがあることで冪等性を保つことができます。</td>
</tr>
</tbody>
</table>
<p>

</p>
<p class="wp-block-paragraph">

</p>
<p class="wp-block-paragraph">

</p>
<h3 class="wp-block-heading">サービスファイルの作成</h3>
<p>

</p>
<p class="wp-block-paragraph">roles/kafka_broker/task/main.yaml と roles/kafka_controller/task/main.yaml にサービスファイルを作成するタスクを記載しています。内容は同じです。</p>
<pre><code class="code-line" dir="auto" data-line="326">- name: Copy template of kafka broker service file
  ansible.builtin.template:
    src: ./roles/common/templates/kafka_service_template.j2
    dest: /etc/systemd/system/kafka-broker.service
  become: true</code></pre>
<p>ansible.builtin.template は構築対象サーバにテンプレートファイルをコピーします。その際テンプレートファイル内の変数を変数の値に置き換えた上でコピーします。ここでは src に指定した Ansible サーバ上のテンプレートファイルを dest で指定した構築対象サーバ上のファイルにコピーします。<br />テンプレートファイルは以下の通りです。</p>
<p>

</p>
<p class="wp-block-paragraph">roles/common/templates/kafka_service_template.j2</p>
<pre><code class="code-line" dir="auto" data-line="337">[Unit]
Description=Kafka server ({{process_role}})
Documentation=https://kafka.apache.org/documentation/

[Service]
Type=simple
Environment="LOG_DIR=/var/log/kafka/{{process_role}}"
ExecStart={{install_dir}}/{{kafka_dir}}/bin/kafka-server-start.sh {{path_to_properties}}
ExecStop={{install_dir}}/{{kafka_dir}}/bin/kafka-server-stop.sh --process-role={{process_role}}

[Install]
WantedBy=multi-user.target</code></pre>
<p>このようなサービスファイルを用いて systemctl で Kafka の起動が行えるようにすることで起動状態の管理を楽にしています。</p>
<p>

</p>
<p class="wp-block-paragraph">変数 process_role と path_to_properties は、Broker 用と Controller 用で変わるようになっていて、Broker か Controller かによってサービスファイルの内容が変わるようになっています。</p>
<p>

</p>
<p class="wp-block-paragraph">Environment として LOG_DIR を設定していますが、これによってログ出力先（Kafka でやり取りされるメッセージという意味のログではなく、サーバのエラー等を出力するログのこと）を指定できます。</p>
<p>

</p>
<p class="wp-block-paragraph">ExecStart では起動コマンドを指定しますが、kafka_2.13-4.0.0.tgz の bin ディレクトリにある kafka-server-start.sh を使用します。kafka-server-start.sh {設定ファイルのパス} と実行することで起動しますが、設定ファイルが Broker のものなら Brokerが、Controller のものなら Controller が起動します。</p>
<p>

</p>
<p class="wp-block-paragraph">ExecStop では終了コマンドを指定しますが、kafka_2.13-4.0.0.tgz の bin ディレクトリにある kafka-server-stop.sh を使用します。kafka-server-stop.sh は引数なしだとそのマシン上のすべての Kafka プロセスを終了させてしまうため、<code>--process-role</code> を指定することで指定したプロセスのみを終了させています。</p>
<p>

</p>
<p class="wp-block-paragraph">このように Kafka の起動、終了にもスクリプトを使うのですが、systemctl を使うようにすることで ansible.builtin.systemd_service モジュールを使用できるので shell モジュールを避けることができます。</p>
<p>

</p>
<h3 class="wp-block-heading">起動</h3>
<p>

</p>
<p class="wp-block-paragraph">

</p>
<p class="wp-block-paragraph">roles/kafka_broker/task/main.yaml に Broker プロセスを起動するタスクを記載しています。</p>
<pre><code class="code-line" dir="auto" data-line="368">- name: Start Kafka broker
  ansible.builtin.systemd_service:
    name: kafka-broker.service
    state: started
    daemon_reload: true
  become: true</code></pre>
<p>ansible.builtin.systemd_service は name で指定したサービスを state で指定した状態にします。今回は起動した状態にしたいので started としています。</p>
<p>

</p>
<p class="wp-block-paragraph">daemon_reload:true としているのは起動前に systemctl daemon-reload を実行し直前でコピーしたサービスファイルを読み込ませるためです。</p>
<p>

</p>
<p class="wp-block-paragraph">roles/kafka_controller/tasks/main.yaml に Controller プロセスを起動するタスクを記載しています。</p>
<pre><code class="code-line" dir="auto" data-line="382">- name: Start Kafka controller
  ansible.builtin.systemd_service:
    name: kafka-controller.service
    state: started
    daemon_reload: true
  become: true</code></pre>
<p>起動させるのが Controller であること以外は Broker の場合と同じです。</p>
<p>

</p>
<h2 class="wp-block-heading">終了</h2>
<p>

</p>
<p class="wp-block-paragraph">

</p>
<p class="wp-block-paragraph">roles/terminate_kafka_broker/tasks/main.yaml に Broker プロセスを終了するタスクを記載しています。</p>
<pre><code class="code-line" dir="auto" data-line="407">- name: Stop kafka broker
  ansible.builtin.systemd_service:
    name: kafka-broker.service
    state: stopped
  become: true</code></pre>
<p>ansible.builtin.systemd_service で state を stopped にすることで Broker プロセスを終了させています。</p>
<p>

</p>
<p class="wp-block-paragraph">roles/terminate_kafka_controller/tasks/main.yaml に Controller プロセスを終了するタスクを記載しています。</p>
<pre><code class="code-line" dir="auto" data-line="417">- name: Stop kafka controller
  ansible.builtin.systemd_service:
    name: kafka-controller.service
    state: stopped
  become: true</code></pre>
<p>

</p>
<p class="wp-block-paragraph">対象が Controller になっている点以外は Broker の場合と同じです。</p>
<h2 id="playbook-%E5%AE%9F%E8%A1%8C" class="code-line" dir="auto" data-line="396">Playbook 実行</h2>
<p class="code-line" dir="auto" data-line="397">実行コマンドは以下の通りです。</p>
<pre><code class="code-line" dir="auto" data-line="398">$ ansible-playbook -i inventory.ini setup_servers.yaml --ask-become-pass -v
</code></pre>
<pre><code class="code-line" dir="auto" data-line="401">$ ansible-playbook -i inventory.ini terminate_servers.yaml --ask-become-pass -v</code></pre>
<p>

</p>
<p class="wp-block-paragraph">

</p>
<h2 class="wp-block-heading">動作確認</h2>
<p class="wp-block-paragraph">Kafka クラスターの動作確認としてトピック作成、Produce、Consume を行います。ここでは kafka_2.13-4.0.0.tgz の bin ディレクトリにある kafka-topics.sh、kafka-console-producer.sh、kafka-console-consumer.sh を用います。</p>
<p>

</p>
<ul>
<li>トピックの作成は以下のように行います。</li>
</ul>
<pre><code class="code-line" dir="auto" data-line="398">$ ./bin/kafka-topics.sh --bootstrap-server kafka_controller1.example.com:9092 --create --topic test --partitions 5 --replication-factor 5
Created topic test.</code></pre>
<p class="wp-block-paragraph">kafka-topics.sh でトピックを作成できます。<br /><code class="code-line" dir="auto" data-line="398">--bootstrap-server kafka_controller1.example.com:9092</code><br />で接続先の Broker を指定するので環境によって変えます。成功すれば Created topic test. と出力されます。</p>
<ul>
<li>メッセージの Produce、Consume は以下のように行います。</li>
</ul>
<p>ターミナルを2つ開いておきます。</p>
<p>Producer 側のターミナルではkafka-console-producer.sh を用います。</p>
<pre><code class="code-line" dir="auto" data-line="404">$ ./bin/kafka-console-producer.sh --bootstrap-server kafka_controller1.example.com:9092 --topic test
&gt;hoge #プロンプトが表示されたら入力</code></pre>
<p>Consumer 側のターミナルでは kafka-console-consumer.sh を用います。</p>
<pre><code class="code-line" dir="auto" data-line="411">$ ./bin/kafka-console-consumer.sh --bootstrap-server kafka_controller1.example.com:9092 --topic test --from-beginning
hoge #Producer 側で入力すると表示される</code><code class="code-line" dir="auto" data-line="404"></code></pre>
<p>Producer 側で入力した内容が Consumer 側で表示されれば成功です。メッセージの送受信ができることが確認できました。</p>
<h2 class="wp-block-heading">おわりに</h2>
<p>

</p>
<p class="wp-block-paragraph">今回は Kafka クラスターの動作に必要な最低限の設定方法をご紹介しました。<br />同じように Kafka クラスターを構築する方の助けとなれば幸いです。</p>
<p>

</p>
<p class="wp-block-paragraph"></p>]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
