1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

docker v26 にしたら haproxy の https化が死んだ! - ipv6絡みでした

Posted at

httpアプリのhttps化は、haproxyが超絶便利

docker compose使ってると、複数コンテナの組み合わせだけで簡単に機能を構成出来ますよね。
http -> https のターミネーションには、 haproxy がめちゃ便利です。

以下はサンプルコードです。(https化そのものはこの記事のスコープ外としますのでまだの方、ぜひ使い方を調べてみてください。)

docker-compose.yaml
version: '3'

services:
  haproxy:
    image: haproxy:latest
    volumes:
      - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
      - ./certs/haproxy.pem:/etc/ssl/private/haproxy.pem
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - webapp

  webapp:
    image: your_webapp_image
    ports:
      - "8080:80"
haproxy.cfg
global
    log stdout format raw local0

defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend http-in
    bind *:80
    bind *:443 ssl crt /etc/ssl/private/haproxy.pem
    redirect scheme https code 301 if !{ ssl_fc }

    default_backend servers

backend servers
    server webapp1 webapp:80 check

docker engine v26 以上に上げると動作しない?

Screenshot 2024-06-24 at 17.20.30.png

無慈悲な画像ェ...

こっからそれはもうドツボにハマったのですが、まず解決策から

tl:dr; コンテナ内のデフォルトネットワーキングが IPV6になった!

散々迷路に入りながら色々調べたのですが、haproxy コンテナ内から各コンテナへの ping が通ることを確認して、ふと localhost に ping を打ったら...

docker exec -it mai-haproxy-1 bash

root@6272410af66d:/var/lib/haproxy# ping localhost
PING localhost(localhost (::1)) 56 data bytes
64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.038 ms

えっ (::1) ???
そうです、docker engine v26の何かの変更で、haproxyコンテナ内部のネットワーキングのデフォルトが ipv6 になったようで。

僕の環境では次のように、http -> httpsのリダイレクトを実装していたのですが、
この localhost:8080 の部分の通信が闇に吸われて行ってしました。

🆖❌ haproxy.cfg
# http / https で二つのバックエンドを持つ
# 振り分けのために「このコンテナ内でのみ有効なポート」を使うループバックを二つ立ち上げる
backend http_back
mode tcp
server loopback-for-http localhost:8080

backend https_back
mode tcp
server loopback-for-https localhost:8443

こちらを、localhost -> 127.0.0.1 に置き換えると、
最新の docker v26でも動作するようになりました!

🆗🙆‍♀ haproxy.cfg
# http / https で二つのバックエンドを持つ
# 振り分けのために「このコンテナ内でのみ有効なポート」を使うループバックを二つ立ち上げる
backend http_back
mode tcp
server loopback-for-http 127.0.0.1:8080

backend https_back
mode tcp
server loopback-for-https 127.0.0.1:8443

しばらく古いバージョンの docker に apt-mark hold して対応していたのですが、
最新環境でも動くように修正できて良かったです!

この件、気づくまでマジでどツボりましたのでどなたかの役に立てば...

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?