ホストサービスにアクセスするDockerでのサービスの実装

ホストサービスにアクセスするDockerでのサービスの実装

1. シナリオ

日常の開発およびテスト作業には Windows と WSL2 を使用します。 しかし、wsl2 ではネットワークの問題が頻繁に発生します。たとえば、今日私は、オープンソース コンポーネント synch を使用して postgres データを clickhouse に同期することを主な機能とするプロジェクトをテストしています。

テストに必要なコンポーネント

  1. ポストグレ
  2. カフカ
  3. 飼育係
  4. レディス
  5. 同期コンテナ

当初のテストでは、docker-compose を使用して上記 5 つのサービスをオーケストレーションし、network_modules で hosts モードを使用するというソリューションを選択しました。Kafka のリスニング セキュリティ メカニズムを考慮すると、このネットワーク モードでは公開ポートを個別に指定する必要はありません。

docker-compose.yamlファイルは以下のとおりです

バージョン: "3"
 
サービス:
  ポストグル:
    画像: failymao/postgres:12.7
    コンテナ名: postgres
    再起動: 停止しない限り
    privileged: true # docker-compose 環境変数を設定するコマンド: [ "-c", "config_file=/var/lib/postgresql/postgresql.conf", "-c", "hba_file=/var/lib/postgresql/pg_hba.conf" ]
    ボリューム:
      - ./config/postgresql.conf:/var/lib/postgresql/postgresql.conf
      - ./config/pg_hba.conf:/var/lib/postgresql/pg_hba.conf
    環境:
      POSTGRES_パスワード: abc123
      POSTGRES_USER: postgres
      ポート: 15432
      POSTGRES_ホスト: 127.0.0.1
    ヘルスチェック:
      テスト: sh -c "sleep 5 && PGPASSWORD=abc123 psql -h 127.0.0.1 -U postgres -p 15432 -c '\q';"
      間隔: 30秒
      タイムアウト: 10秒
      再試行: 3
    ネットワークモード: "ホスト"
 
  飼育員:
    画像: failymao/zookeeper:1.4.0
    コンテナ名: 飼育係
    再起動: 常に
    ネットワークモード: "ホスト"
 
  カフカ:
    画像: failymao/kafka:1.4.0
    コンテナ名: kafka
    再起動: 常に
    依存:
      - 動物園の飼育員
    環境:
      KAFKA_ADVERTISED_HOST_NAME: カフカ
      KAFKA_ZOOKEEPER_CONNECT: ローカルホスト:2181
      KAFKA_LISTENERS: プレーンテキスト://127.0.0.1:9092
      KAFKA_ADVERTISED_LISTENERS: プレーンテキスト://127.0.0.1:9092
      KAFKA_ブローカーID: 1
      KAFKA_ログ保持時間: 24
      KAFKA_LOG_DIRS: /data/kafka-data #データ mountnetwork_mode: "host"
 
  プロデューサー:
    依存:
      - レディス
      - カフカ
      - 動物園の飼育員
    画像: long2ice/synch
    コンテナ名: プロデューサー
    コマンド: sh -c "
      睡眠30 &&
      同期 --alias pg2ch_test 生成"
    ボリューム:
      - ./synch.yaml:/synch/synch.yaml
    ネットワークモード: "ホスト"
 
  # コンシューマーはデータベース コンシューマーを消費します:
    端末: 真
    依存:
      - レディス
      - カフカ
      - 動物園の飼育員
    画像: long2ice/synch
    コンテナ名: コンシューマー
    コマンド: sh -c
      「30分寝て
      同期 --alias pg2ch_test 消費 --schema pg2ch_test"
    ボリューム:
      - ./synch.yaml:/synch/synch.yaml
    ネットワークモード: "ホスト"
 
  レディス:
    ホスト名: redis
    コンテナ名: redis
    画像: redis:latest
    ボリューム:
      - redis:/データ
    ネットワークモード: "ホスト"
 
ボリューム:
  レディス:
  カフカ:
  飼育員:

テスト中は、postgres と wal2json コンポーネントを使用する必要がありました。コンテナにコンポーネントを個別にインストールするのは非常に面倒でした。何度か試しましたが、失敗しました。そこで、ホスト マシンに postgres サービスをインストールすることにしました。コンテナ内の同期サービスは、ホスト マシンの IP とポートを使用します。

しかし、サービスを再起動した後、同期サービスはまだ起動できず、ログにはpostgresが接続できないと表示されます。同期構成ファイルは次のとおりです。

コア:
  debug: true # True に設定すると、SQL 情報が表示されます。
  insert_num: 20000 # 送信するnumの数。本番環境では20000に設定することを推奨します。
  insert_interval: 60 # 送信する秒数。本番環境では60に設定することを推奨します。
  # これを有効にすると、ClickHouse でデータベース `synch` が自動的に作成され、モニターデータが挿入されます
  監視: 有効
 
レディス:
  ホスト: redis
  ポート: 6379
  デシベル: 0
  パスワード:
  プレフィックス: 同期
  sentinel: false # redis sentinel を有効にする
  sentinel_hosts: # redis センチネルホスト
    - 127.0.0.1:5000
  sentinel_master: マスター
  queue_max_len: 200000 # ストリームの最大長。FIFO で冗長なものを削除します。
 
ソースDB:
  -db_type: ポストグル
    エイリアス: pg2ch_test
    broker_type: kafka # 現在、redis と kafka をサポートしています
    ホスト: 127.0.0.1
    ポート: 5433
    ユーザー: postgres
    パスワード: abc123
    データベース:
      - データベース: pg2ch_test
        自動作成: 有効
        表:
          - テーブル: pgbench_accounts
            自動フルETL: 有効
            clickhouse_engine: マージツリーの折りたたみ
            sign_column: サイン
            バージョン列:
            パーティションの基準:
            設定:
 
クリックハウス:
  # クラスターの場合、シャードホストはランダムに挿入されます
  ホスト:
    - 127.0.0.1:9000
  ユーザー: デフォルト
  パスワード: ''
  cluster_name: # 空でない場合はクラスター モードを有効にします。有効にする場合は、ホストが複数である必要があります。
  分散テーブルサフィックス: _all # クラスターで使用可能な分散テーブルサフィックス
 
カフカ:
  サーバー:
    - 127.0.0.1:9092
  topic_prefix: 同期

この状況は非常に奇妙です。まず、postgres が起動しており、リスニング ポート (ここでは 5433) が正常であることを確認します。localhost とホストの eth0 ネットワーク カード アドレスの両方でエラーが報告されています。

2. 解決策

Googleの回答、stackoverflowの高評価の回答を参照すると、問題は解決しました。元の回答は次のとおりです。

Docker-for-mac または Docker-for-Windows 18.03+ を使用している場合は、ホスト host.docker.internal (接続文字列の 127.0.0.1 の代わりに) を使用して、mysql サービスに接続するだけです。

Docker-for-Linux 20.10.0以降を使用している場合は、Dockerを起動したときにホストhost.docker.internalを使用することもできます。

--add-host host.docker.internal:host-gateway オプションを指定したコンテナ。

それ以外の場合は以下をお読みください

docker run コマンドで ** --network="host" ** を使用すると、docker コンテナ内の 127.0.0.1 が docker ホストを指すようになります。

詳細についてはソース投稿をご覧ください

ホストモードでは、コンテナ内のサービスはホストマシン上のサービスにアクセスします。

エラーを解決するには、postgres リスニング アドレスを host.docker.internal に変更します。 ホストマシンの/etc/hostsファイルを次のように確認します。

root@failymao-NC:/mnt/d/pythonProject/pg_2_ch_demo# cat /etc/hosts
# このファイルは WSL によって自動的に生成されました。このファイルの自動生成を停止するには、/etc/wsl.conf に次のエントリを追加します。
# [ネットワーク]
# 生成ホスト = false
127.0.0.1 ローカルホスト
 
10.111.130.24 ホスト.docker.内部

ホスト IP とドメイン名のマッピングを確認できます。ドメイン名にアクセスすると、ホスト IP に解決され、ホスト サービスにアクセスします。

最後に、同期サービスの構成は次のとおりです。

コア:
  debug: true # True に設定すると、SQL 情報が表示されます。
  insert_num: 20000 # 送信するnumの数。本番環境では20000に設定することを推奨します。
  insert_interval: 60 # 送信する秒数。本番環境では60に設定することを推奨します。
  # これを有効にすると、ClickHouse でデータベース `synch` が自動的に作成され、モニターデータが挿入されます
  監視: 有効
 
レディス:
  ホスト: redis
  ポート: 6379
  デシベル: 0
  パスワード:
  プレフィックス: 同期
  sentinel: false # redis sentinel を有効にする
  sentinel_hosts: # redis センチネルホスト
    - 127.0.0.1:5000
  sentinel_master: マスター
  queue_max_len: 200000 # ストリームの最大長。FIFO で冗長なものを削除します。
 
ソースDB:
  -db_type: ポストグル
    エイリアス: pg2ch_test
    broker_type: kafka # 現在、redis と kafka をサポートしています
    ホスト: host.docker.internal
    ポート: 5433
    ユーザー: postgres
    パスワード: abc123
    データベース:
      - データベース: pg2ch_test
        自動作成: 有効
        表:
          - テーブル: pgbench_accounts
            自動フルETL: 有効
            clickhouse_engine: マージツリーの折りたたみ
            sign_column: サイン
            バージョン列:
            パーティションの基準:
            設定:
 
クリックハウス:
  # クラスターの場合、シャードホストはランダムに挿入されます
  ホスト:
    - 127.0.0.1:9000
  ユーザー: デフォルト
  パスワード: ''
  cluster_name: # 空でない場合はクラスター モードを有効にします。有効にする場合は、ホストが複数である必要があります。
  分散テーブルサフィックス: _all # クラスターで使用可能な分散テーブルサフィックス
 
カフカ:
  サーバー:
    - 127.0.0.1:9092
  topic_prefix: 同期ホスト: host.docker.internal
コア:
  debug: true # True に設定すると、SQL 情報が表示されます。
  insert_num: 20000 # 送信するnumの数。本番環境では20000に設定することを推奨します。
  insert_interval: 60 # 送信する秒数。本番環境では60に設定することを推奨します。
  # これを有効にすると、ClickHouse でデータベース `synch` が自動的に作成され、モニターデータが挿入されます
  監視: 有効
 
レディス:
  ホスト: redis
  ポート: 6379
  デシベル: 0
  パスワード:
  プレフィックス: 同期
  sentinel: false # redis sentinel を有効にする
  sentinel_hosts: # redis センチネルホスト
    - 127.0.0.1:5000
  sentinel_master: マスター
  queue_max_len: 200000 # ストリームの最大長。FIFO で冗長なものを削除します。
 
ソースDB:
  -db_type: ポストグル
    エイリアス: pg2ch_test
    broker_type: kafka # 現在、redis と kafka をサポートしています
    ホスト: 
    ポート: 5433
    ユーザー: postgres
    パスワード: abc123
    データベース:
      - データベース: pg2ch_test
        自動作成: 有効
        表:
          - テーブル: pgbench_accounts
            自動フルETL: 有効
            clickhouse_engine: マージツリーの折りたたみ
            sign_column: サイン
            バージョン列:
            パーティションの基準:
            設定:
 
クリックハウス:
  # クラスターの場合、シャードホストはランダムに挿入されます
  ホスト:
    - 127.0.0.1:9000
  ユーザー: デフォルト
  パスワード: ''
  cluster_name: # 空でない場合はクラスター モードを有効にします。有効にする場合は、ホストが複数である必要があります。
  分散テーブルサフィックス: _all # クラスターで使用可能な分散テーブルサフィックス
 
カフカ:
  サーバー:
    - 127.0.0.1:9092
  topic_prefix: 同期

3. 結論

--networks="host" モードでコンテナを起動する場合、コンテナ内のホスト上のサービスにアクセスするには、IP を `host.docker.internal` に変更します。

4. 参考文献

https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach

これで、docker でホスト サービスにアクセスするサービスの実装に関するこの記事は終了です。docker でホストにアクセスすることについての関連コンテンツをさらにご覧になりたい場合は、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Dockerコンテナを使用してホストネットワークにアクセスする方法
  • Dockerでローカルマシン(ホストマシン)にアクセスする方法
  • Dockerコンテナがホストポートにアクセスできない場合の解決策
  • Dockerコンテナにホストディレクトリへの書き込み権限がない場合の解決策
  • Dockerコンテナとホスト間のデータ相互作用の概要
  • Dockerコンテナとホストマシン間の8時間の差の問題を解決する

<<:  JPG、GIF、PNGなどのさまざまな画像形式の詳細な説明

>>:  Vue ページ状態の永続化の詳細な説明

推薦する

Linux CentOS 6.5 ifconfig が IP を照会できない問題の解決方法

最近、何人かの友人から、仮想マシンに CentOS をインストールした後、ifconfig コマンド...

Nginx 環境での WordPress マルチサイト構成の詳細な説明

WordPress のマルチサイト機能を使用すると、1 つの WordPress プログラムをインス...

MySQL マスタースレーブ同期の原理と応用

目次1. マスタースレーブ同期原理マスタースレーブ同期アーキテクチャ図(非同期同期)マスタースレーブ...

Vue3とVue2の利点のまとめ

目次1. なぜ vue3 が必要なのでしょうか? 2. vue3の利点3. 応答原則の違い4. ライ...

ネイティブ JavaScript でショッピングカートを実装する

この記事では、ショッピングカートを実装するためのJavaScriptの具体的なコードを参考までに紹介...

Iframe の内外のページで JS がどのように動作するかの概要

目次iframeの外側のiframeのコンテンツを取得する方法1方法2 iframe 内の ifra...

ReactプロジェクトでのTypeScriptの実装

目次1. はじめに2. 使用方法ステートレスコンポーネントステートフルコンポーネント制御コンポーネン...

Centos で MySQL パスワードを変更する方法

1. MySQL ログイン設定を変更します。 # vim /etc/my.cnf文を追加: skip...

MySQL 5.7 解凍版のインストール、アンインストール、および文字化けしたコードの問題のグラフィック解決

1. 解凍版のインストール(1)圧縮パッケージをダウンロードし、ディスクの場所に解凍します。圧縮パッ...

dl、dt、dd リスト ラベルの例

dd タグと dt タグはリストに使用されます。通常は <ul><li> タ...

MySQL 5.7.30 のインストールとアップグレードの問題に関する詳細なチュートリアル

くさびコンピュータにインストールされている MySQL のバージョンが比較的古く、おそらくバージョン...

MySQLの読み書き分離により挿入後にデータが選択されなくなる問題を解決

MySQLは独立した書き込み分離を設定します。コードに次のものを書くと問題が発生する可能性があります...

WeChatアプレットでvantフレームワークを使用するための具体的な手順

目次1. アプレットのプロジェクト ディレクトリを開き、ファイルの場所を開きます。 2. プロジェク...

MySQL エラー コード 1862 の解決方法: パスワードの有効期限が切れています

ブロガーは 1 ~ 2 か月間 MySQL を使用していませんでしたが、今日この問題に遭遇しました。...

jQuery は拡張アニメーションによるナビゲーション バー効果を実装します

展開アニメーション効果のあるナビゲーションバーを設計してカスタマイズし、デモを作成してみました。設計...