複数の Docker コンテナが同じポート番号を持たない場合の解決策

複数の Docker コンテナが同じポート番号を持たない場合の解決策

背景

Dockerでは、同じイメージを使用して4つのコンテナを作成します。ネットワークはブリッジモードです。サービスAは、4つのコンテナすべてで同じポート番号(6000)を使用します。外部に公開されるポートの数を減らすために、4つのサービスインスタンスのプロキシとしてnginxを使用します。4つのサービスインスタンスは4つのアップストリームに属しており、4つのインスタンスへのアクセスには/service1や/service2などのパスが使用されます。

現時点では、ローカルで何らかのサービスにアクセスすると 502 エラーが報告され、困惑します。

アップストリームへの接続中に connect() が失敗しました (111: 接続が拒否されました)

ファイルを作成

バージョン: '2'
ネットワーク:
 んん:
  ドライバー: ブリッジ
サービス:
 サービス1:
  コンテナ名: サービス1
  画像: foo
  ネットワーク:
   -んんん
  ボリューム:
   - ./logs/1:/apps/aaa/bbb-logs
   - ./common:/apps/aaa/bbb
   - ./xxx/1.xml:/ccc/targets.xml
  エントリポイント: foo.sh
  コマンド: start app=foo port=6000
  
 サービス2:
  コンテナ名: サービス2
  画像: foo
  ネットワーク:
   -んんん
  ボリューム:
   - ./logs/2:/apps/aaa/bbb-logs
   - ./common:/apps/aaa/bbb
   - ./xxx/2.xml:/ccc/targets.xml
  エントリポイント: foo.sh
  コマンド: start app=foo port=6000
 
 サービス3:
  コンテナ名: サービス3
  画像: foo
  ネットワーク:
   -んんん
  ボリューム:
   - ./logs/3:/apps/aaa/bbb-logs
   - ./common:/apps/aaa/bbb
   - ./xxx/3.xml:/ccc/targets.xml
  エントリポイント: foo.sh
  コマンド: start app=foo port=6000
 
 サービス4:
  コンテナ名: サービス4
  画像: foo
  ネットワーク:
   -んんん
  ボリューム:
   - ./logs/4:/apps/aaa/bbb-logs
   - ./common:/apps/aaa/bbb
   - ./xxx/4.xml:/ccc/targets.xml
  エントリポイント: foo.sh
  コマンド: start app=foo port=6000  
 
 nginx:
  コンテナ名: nginx
  イメージ: nginx:1.15-alpine
  ポート:
   - 6001:6001
  ネットワーク:
   -んんん
  ボリューム:
   ./nginx/nginx.conf:/etc/nginx/nginx.conf
   nginx のログファイル

nginx.conf

ワーカープロセス数 8;
ワーカー_rlimit_nofile 65535; 
イベント {
    epoll を使用します。
    ワーカー接続 65535;
 }
 
http {
    mime.types を含めます。
    default_type アプリケーション/オクテットストリーム;
    ファイル送信オン;
    log_format main '[$time_local]$remote_addr-$upstream_addr "$request" $status $body_bytes_sent';
 
    アップストリームサービス1.local {
      サーバーサービス-1:6000;
    }
    アップストリームサービス2.local {
     サーバーサービス2:6000;
    }
    アップストリームサービス3.local {
      サーバーサービス3:6000;
    }
    アップストリームサービス4.local {
      サーバーサービス-4:6000;
    }
 
    サーバー{
      6001を聴く;
      クライアントの最大ボディサイズは100Mです。
      proxy_set_header ホスト $host:$server_port;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
      場所 /service1/ {
        proxy_pass http://service1.local/;
      }
      場所 /service2/ {
        proxy_pass http://service2.local/;
      }
      場所 /service3/ {
        proxy_pass http://service3.local/;
      }
      場所 /service4/ {
        proxy_pass http://service4.local/;
      }
      場所 /nginx_status {
        stub_status オン;
        access_log オフ;
      }
    }
}
 

このとき、 curl localhost:6001/service1/api/v1/.... は上記の 502 エラーを報告します。各コンテナには独自のネットワーク カードがあり、異なるコンテナのポート番号が競合しないのは当然です。

解決

現時点ではこれより良い解決策はないので、4 つのサービスに異なるポート番号を使用し、それに応じて nginx を変更するしかありません。

補足: 同じサーバーに複数の Docker コンテナをデプロイするとポートリダイレクトの問題が発生する

実稼働環境では、複数のコンテナをデプロイし、複数のポートにアクセスします。

例: -p 80:80 -p 81:81

アドレス81が存在する場合は、ポート80のアドレスに直接アクセスします。

誤解: 最初はクッキーを更新したのでクッキーの問題だと思った (クッキーはポート番号を区別しない)

ついに理由が分かりました: リダイレクトの問題。ログアウトするとログインページにリダイレクトされるからです。

解決策: nginxパラメータを設定する

proxy_set_header HOST $host; は proxy_set_header HOST $host:81; になります。

なぜなら、リクエストパラメータには必ずポート番号が含まれるからです。

インターネット上には別の方法があります: proxy_redirect パラメータを変更する (ただし、試しても機能しませんでした)

上記は私の個人的な経験です。参考になれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。間違いや不備な点がありましたら、遠慮なくご指摘ください。

以下もご興味があるかもしれません:
  • Dockerでudpポート番号を指定する問題を解決する
  • Raspberry Pi シリーズ: Docker を使用して Qinglong Panel をインストールし、ポート番号の設定の問題を変更する

<<:  MySQL 8.0 redo ログの詳細な分析

>>:  Vue のライフサイクルとフック関数の詳細な説明と典型的な面接の質問

推薦する

htmlハイパーリンクaのクリックイベントの後、hrefで指定されたアドレスにジャンプします。

場合によっては、ジャンプを完了するために href の代わりにハイパーリンク <a> を...

React+Ant Design開発環境をセットアップするための実装手順

基礎1. スキャフォールディングを使用してプロジェクトを作成し、開始する1.1 足場を設置する: n...

Dockerコマンドは一般ユーザーが実行できるように実装されている

dockerをインストールすると、通常はdockerユーザーグループが作成されます。ステップ2: 現...

幅の比率に応じて高さを変えるCSSを実装するいくつかの方法

[解決策1: パディングの実装]原理:要素の padding の値がパーセンテージの場合、このパーセ...

MySQLクエリ最適化プロセスを理解する

目次パーサーとプリプロセッサクエリオプティマイザーMySQL クエリの最適化には、解析、前処理、最適...

コマンドラインを使用してUbuntuのバージョンを検出する方法

方法1: lsb_releaseユーティリティを使用するlsb_release ユーティリティは、L...

Ubuntu 18.04 LTSでIPアドレスを設定するための完全な手順

序文Ubuntu 18.04 LTS で IP アドレスを設定する方法は、これまで使用されていた設定...

ウェブサイトのユーザビリティを向上させる10のヒント

企業の Web サイト、個人のブログ、ショッピング Web サイト、ゲーム Web サイトなど、どの...

MySQL の null と not null、null と空の値の違いの詳細な説明 ''''

MySQL を長い間使用してきた多くの人は、これら 2 つのフィールド属性の概念をまだよく理解して...

MySQL8 ベースの docker-compose デプロイメント プロジェクトの実装

1. まず、次のパスに従って対応するフォルダを作成します。 ローカルのdockerでmysqlを実行...

Vue の詳細な入門ノート

目次1. はじめに2. 初期ビュー(I) Vueの概念を理解する(II) MVVMアーキテクチャ(I...

Windows が MySQL サービスを開始できず、エラー 1067 を報告する場合の解決策

突然、MySQLにログインすると、アクセスが拒否されたか、データベースに接続できないと表示されました...

マウスを傾けた状態でのフリップナビゲーションの問題に関する研究

この記事では、マウス フリップナビゲーションの制作についてまだ疑問を持っている友人の役に立つことを期...

Vueはアップロードコンポーネントを実装します

目次1. はじめに2. アイデアファイルをアップロードする2つの方法3. ライフサイクル4. コード...

Nginx 構成 クロスドメイン リクエスト Access-Control-Allow-Origin * 詳細な説明

序文403 クロスオリジン エラーが発生しNo 'Access-Control-Allow-...