<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Haproxy on K-Life Hack | システムアーキテクチャ &amp; DevOps</title><link>https://klifehack.com/tags/haproxy/</link><description>Recent content in Haproxy on K-Life Hack | システムアーキテクチャ &amp; DevOps</description><generator>Hugo -- gohugo.io</generator><language>ja</language><lastBuildDate>Fri, 29 May 2026 17:40:32 +0900</lastBuildDate><atom:link href="https://klifehack.com/tags/haproxy/index.xml" rel="self" type="application/rss+xml"/><item><title>HAProxyとSpring Boot Actuatorを用いたBlue/Greenデプロイメントの構成とヘルスチェックの最適化</title><link>https://klifehack.com/p/haproxy-spring-boot-blue-green-deployment/</link><pubDate>Fri, 29 May 2026 17:40:32 +0900</pubDate><guid>https://klifehack.com/p/haproxy-spring-boot-blue-green-deployment/</guid><description>&lt;h1 id="haproxyとspring-boot-actuatorによる高可用性インフラとbluegreenデプロイメントの最適化"&gt;HAProxyとSpring Boot Actuatorによる高可用性インフラとBlue/Greenデプロイメントの最適化
&lt;/h1&gt;&lt;p&gt;本稿では、HAProxyとSpring Boot Actuatorを基盤とした高可用性インフラストラクチャの構築、およびBlue/Greenデプロイメント戦略の実装詳細について分析します。特に、サービス停止時間をゼロにするためのトラフィック制御と、アプリケーションのライフサイクル管理におけるヘルスチェックの役割に焦点を当て、堅牢なシステム構成を検証します。&lt;/p&gt;
&lt;h2 id="1-デプロイメント環境におけるセキュリティプロトコル"&gt;1. デプロイメント環境におけるセキュリティプロトコル
&lt;/h2&gt;&lt;p&gt;AWSやVercelなどのクラウドプラットフォームにおいて、セッション管理の安全性を確保するためには、クッキーベースの認証に対する厳格な属性設定が求められます。クロスサイトスクリプティング（XSS）およびクロスサイトリクエストフォージェリ（CSRF）のリスクを軽減するため、以下の属性の実装が不可欠です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;SameSite&lt;/b&gt;: クロスサイトリクエストにおけるクッキーの送信範囲を制限し、意図しないリクエストを遮断します。&lt;/li&gt;
&lt;li&gt;&lt;b&gt;HttpOnly&lt;/b&gt;: クライアントサイドのスクリプトによるクッキーへのアクセスを禁止し、トークン漏洩を防止します。&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Secure&lt;/b&gt;: HTTPSプロトコルを介した暗号化通信時のみクッキーを送信するよう強制します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの設定は、ロードバランサやアプリケーションプロキシのレイヤーで適切に処理される必要があります。&lt;/p&gt;
&lt;h2 id="2-spring-boot-actuatorによる監視とヘルス管理"&gt;2. Spring Boot Actuatorによる監視とヘルス管理
&lt;/h2&gt;&lt;p&gt;Spring Boot Actuatorは、アプリケーションの稼働状態を外部に公開するためのエンドポイントを提供します。インフラストラクチャのオーケストレーションにおいて、特に重要なエンドポイントは以下の通りです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/actuator/health&lt;/code&gt;: アプリケーションの稼働状態（UP/DOWN）を返却します。HAProxyなどのロードバランサがバックエンドの生存確認を行う際の主要なターゲットとなります。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/actuator/metrics&lt;/code&gt;: JVMのメモリ使用率、CPU負荷、HTTPリクエスト統計などのテレメトリデータを提供し、リソースの最適化を支援します。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/actuator/env&lt;/code&gt;: アプリケーションに適用されている環境変数の構成情報を表示し、デプロイ時の設定不整合を特定します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3-haproxyによるマルチドメインマッピングと負荷分散"&gt;3. HAProxyによるマルチドメインマッピングと負荷分散
&lt;/h2&gt;&lt;p&gt;HAProxyをリバースプロキシおよびロードバランサとして構成し、複数のSpring Bootアプリケーションを単一のドメインに統合します。ACL（Access Control List）を用いたルーティングと、Actuatorを利用したヘルスチェックの設定により、トラフィックの精密な制御が可能となります。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-haproxy" data-lang="haproxy"&gt;defaults
 mode http
 timeout connect 5s
 timeout client 60s
 timeout server 60s
 
frontend http_front
 bind *:80
 # ホストヘッダーに基づいたACLの定義
 acl host_app1 hdr_beg(host) -i app1-127-0-0-1.nip.io

 # 条件に合致する場合にバックエンドへ振り分け
 use_backend http_back_1 if host_app1

backend http_back_1
 balance roundrobin
 # ヘルスチェック構成: ルートパスではなくActuatorエンドポイントを使用
 option httpchk GET /actuator/health
 
 # チェックパラメータ: 2秒間隔、1回の成功でUP、1回の失敗でDOWNと判定
 default-server inter 2s rise 1 fall 1
 
 # サーバー障害時に他のサーバーへリクエストを再試行する設定
 option redispatch

 # バックエンドサーバーの定義
 server app_server_1_1 app1_1:8080 check
 server app_server_1_2 app1_2:8080 check
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="4-bluegreenデプロイメントの実行ワークフロー"&gt;4. Blue/Greenデプロイメントの実行ワークフロー
&lt;/h2&gt;&lt;p&gt;Blue/Greenデプロイメントは、新旧の環境を並行して稼働させ、トラフィックを切り替えることでダウンタイムを排除する手法です。本構成では、Dockerコンテナの入れ替えとシェルスクリプトによるReadiness Probe（準備完了プローブ）を組み合わせます。&lt;/p&gt;
&lt;h3 id="ステップ1-旧コンテナgreenの停止"&gt;ステップ1: 旧コンテナ（Green）の停止
&lt;/h3&gt;&lt;p&gt;まず、&lt;code&gt;app1_2&lt;/code&gt;コンテナを停止・削除します。HAProxyはヘルスチェックの失敗を検知し、トラフィックを自動的に稼働中の&lt;code&gt;app1_1&lt;/code&gt;（Blue）に集約します。&lt;/p&gt;
&lt;h3 id="ステップ2-新コンテナの起動と起動確認"&gt;ステップ2: 新コンテナの起動と起動確認
&lt;/h3&gt;&lt;p&gt;新しいイメージを用いてコンテナを起動し、アプリケーションが完全に初期化されるまで待機します。Actuatorの&lt;code&gt;/health&lt;/code&gt;エンドポイントが&lt;code&gt;UP&lt;/code&gt;を返すまで、旧コンテナの削除を保留する制御が重要です。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 新しいコンテナの起動&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker run -d --network common -p 8081:8080 --name app1_2 chasaem/app260601:1.0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Readiness Probe スクリプト&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;START_TIME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;date +%s&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; true; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; CONTENT&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;curl -s http://localhost:8081/actuator/health&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;[[&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$CONTENT&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; *&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#34;status&amp;#34;:&amp;#34;UP&amp;#34;&amp;#39;&lt;/span&gt;* &lt;span style="color:#f92672"&gt;]]&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;Server is UP!&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; break;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; CURRENT_TIME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;date +%s&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ELAPSED_TIME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$((&lt;/span&gt;CURRENT_TIME &lt;span style="color:#f92672"&gt;-&lt;/span&gt; START_TIME&lt;span style="color:#66d9ef"&gt;))&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;[[&lt;/span&gt; $ELAPSED_TIME -ge &lt;span style="color:#ae81ff"&gt;60&lt;/span&gt; &lt;span style="color:#f92672"&gt;]]&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;Error: Server did not start within 60 seconds.&amp;#34;&lt;/span&gt; &amp;amp;gt;&amp;amp;amp;2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; exit 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sleep 5;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 起動確認後に旧コンテナを削除&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker rm -f app1_1 2&amp;amp;gt; /dev/null
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="5-多層プロキシアーキテクチャ-npmとhaproxyの連携"&gt;5. 多層プロキシアーキテクチャ: NPMとHAProxyの連携
&lt;/h2&gt;&lt;p&gt;SSL/TLS終端と証明書管理を効率化するため、Nginx Proxy Manager (NPM) を最前段に配置する構成を採用します。クライアントからのHTTPSリクエストはNPMで復号され、内部ネットワークを通じてHAProxy（ポート80）へ転送されます。この多層構造により、アプリケーション層の負荷分散とセキュリティ管理を分離することが可能となります。&lt;/p&gt;
&lt;h2 id="6-haproxyヘルスチェックのメカニズム詳細"&gt;6. HAProxyヘルスチェックのメカニズム詳細
&lt;/h2&gt;&lt;p&gt;HAProxyのヘルスチェックパラメータを微調整することで、障害検知の感度とシステムの安定性のバランスを最適化できます。💡&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;inter 2s&lt;/b&gt;: 2秒ごとにヘルスチェックを実行し、状態変化を迅速に捉えます。&lt;/li&gt;
&lt;li&gt;&lt;b&gt;rise 1&lt;/b&gt;: サーバーがDOWN状態からUP状態に復帰するために必要な連続成功回数です。1に設定することで、起動直後のトラフィック投入を迅速化します。&lt;/li&gt;
&lt;li&gt;&lt;b&gt;fall 1&lt;/b&gt;: サーバーをDOWNと判断するために必要な連続失敗回数です。1に設定することで、異常発生時に即座にトラフィックを遮断します。⚠️&lt;/li&gt;
&lt;li&gt;&lt;b&gt;option redispatch&lt;/b&gt;: 選択されたサーバーがリクエスト処理中にダウンした場合、別の健全なサーバーにリクエストを再送出します。これにより、クライアント側でのエラー発生率を低減させます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="7-infrastructure-as-code-iac-によるプロビジョニング"&gt;7. Infrastructure as Code (IaC) によるプロビジョニング
&lt;/h2&gt;&lt;p&gt;AWS EC2インスタンスの構築にはTerraformを使用します。&lt;code&gt;terraform apply&lt;/code&gt;を通じてインフラをコード化し、DNSZIなどの外部DNSサービスでAレコードを管理することで、IPアドレスの変更に伴う運用の複雑さを解消します。構築されたEC2環境上で、前述のHAProxyおよびDockerベースのBlue/Greenデプロイメントロジックを実行し、クラウド環境での動作を検証します。🛠️&lt;/p&gt;
&lt;h2 id="summary"&gt;Summary
&lt;/h2&gt;&lt;p&gt;本構成により、Spring Boot Actuatorによる精密な状態監視と、HAProxyによる柔軟なトラフィック制御を組み合わせた、堅牢なBlue/Greenデプロイメント環境が実現されます。特に、Readiness Probeを自動化スクリプトに組み込むことで、アプリケーションの初期化完了前にトラフィックが流入するリスクを排除し、真のゼロダウンタイムデプロイメントを達成できることが確認されました。&lt;/p&gt;</description></item></channel></rss>