1. 背景 通常、外部サービスを提供する必要がある Docker コンテナの場合、起動時に -p コマンドを使用して外部アクセス ポートを外部に公開します。たとえば、Docker Registry を起動するときに、外部アクセス用にポート 5000 をマップします。 docker run -d -p 5000:5000 レジストリ しかし最近、非常に奇妙な状況に遭遇しました。R&D チームの CentOS 7 テスト環境に Docker レジストリがデプロイされ、ポートが外部に公開されていたのです。コンテナを起動すると、一定期間は正常に動作しますが、無期限の時間が経過すると、外部ホストはウェアハウスからイメージをプルできなくなり、タイムアウトが表示されます。 ただし、Docker ホスト上のリポジトリへのアクセスは通常どおりに実行できます。 この問題に関しては、問題のある Docker デーモン サービスを手動で再起動した後にのみ外部アクセスを復元できますが、しばらくすると問題が再発します。 2. トラブルシューティング この問題に遭遇したとき、私の最初の反応は、グループのメンバーに CentOS 7 独自のファイアウォールを再起動した人がいるかどうかを尋ねることでした。 このサーバーは私が設定したもので、ファイアウォールはオンになっていますが、すでにポートアクセスは開いているので、ファイアウォールが接続をブロックしているからというわけではありません。しかし、この記事は落とし穴の調査文書なので、やはりこの状況を書き出しました。 ケース1: ファイアウォールはオンになっているがポートが開いていない CentOS 7 にはファイアウォール FirewallD が付属しており、有効になっています。次のコマンドで FirewallD のステータスを確認できます。 ファイアウォール-cmd --state 出力が「not running」の場合、FirewallD は実行されておらず、すべての保護ポリシーが開始されていません。この場合、ファイアウォールが接続をブロックしている可能性は排除できます。 出力が「running」の場合、FirewallD が現在実行中であることを意味します。現在開いているポートとサービスを表示するには、次のコマンドを入力する必要があります。 ファイアウォールコマンド --list-ports ファイアウォールコマンド --list-services 現在のファイアウォールはポート 80/tcp、ssh サービス (22/tcp)、dhcpv6-client サービスのみを開いており、Docker コンテナによってマップされたポート 5000/tcp は開いていないことがわかります。 解決策は2つあります。 1. FirewallD サービスをオフにします。 ファイアウォールが不要な場合は、FirewallD サービスをオフにしてください。 systemctl 停止 ファイアウォールd.service 2. 指定したポートを外部に開くポリシーを追加します。 たとえば、外部の 5000/tcp ポートを開きたい場合は、次のコマンドを使用できます。 ファイアウォールコマンド --add-port=5000/tcp --permanent ファイアウォール-cmd --reload ポートを一時的にのみ開きたい場合は、コマンドの最初の行にある「--permanent」パラメータを削除します。その後、FirewallD サービスを再起動すると、このポリシーは無効になります。 ケース2: CentOS 7のFirewallDサービスを手動で再起動する FirewallD は CentOS システムのバージョン 7 で導入された新しいコンポーネントです。簡単に言えば、ファイアウォール関連の設定を簡素化するために使用される iptables のラッパーです。 しかし、FirewallD と Docker は相性がよくありません。FirewallD が起動 (または再起動) すると、iptables から DOCKER チェーンが削除され、Docker が正しく動作しなくなります。
CentOS 7 では、Docker は systemd 構成ファイルに「After=firewalld.service」と明記し、FirewallD の起動後に Docker デーモンが起動するようにしているため、起動時に Docker サービスを自動的に起動するように systemd を設定しても問題はありません。 (ドッカー:私を怒らせる余裕がないなら、私から隠れる余裕はありますか?) ただし、ユーザーが手動で FirewallD サービスを再起動するたびに、FirewallD サービスは Docker デーモンによって iptables に書き込まれた DOCKER チェーンを削除するため、Docker デーモン サービスが DOCKER チェーンを再構築できるように、Docker デーモン サービスを手動で 1 回再起動する必要があります。 しかし、グループ内の他の2人の研究開発担当者に尋ねたところ、2人とも触っていないとのことでした。シェルの履歴を確認しましたが、対応するレコードは見つかりませんでした。 それは奇妙ですね。しかし、しばらく調査した後、ついに新たな理由が見つかりました。 ケース3: IP_FORWARDが有効になっていない 問題を特定できなかったため、倉庫に正常にアクセスできないことが判明すると、R&D チームが手動でホスト マシンにログインし、Docker デーモン サービスを再起動します。 ホスト サーバーにログインして Docker デーモン サービスを再起動する前に、以前 Docker を使用したときに遭遇した別の問題を突然思い出しました。ホスト マシンで IP_FORWARD 機能が有効になっていないと、Docker コンテナーは起動時に警告メッセージを出力します。
また、起動したコンテナでは外部ネットワークにアクセスできなくなり、コンテナによって公開されるポートには外部から正常にアクセスできなくなります。 この障害は、ホスト マシンの IP_FORWARD 機能が有効になっていないことが原因でしょうか? sysctl net.ipv4.ip_forward 確かに、出力には、現在のシステムの IP_FORWARD 機能が無効になっていることが示されています。 しかし問題は、コンテナを起動したときにはすべて正常で、出力がなかったことです。使用中に IP_FORWARD 関数が無効になったのはなぜでしょうか? 待ってください。Docker デーモン サービスは起動時に iptables 設定を自動的に設定します。IP_FORWARD 設定もチェックして、一時的に有効にしてくれるのでしょうか? この仮定に基づいて、Docker デーモン サービスを手動で再起動しました。 案の定、Docker デーモン サービスは起動時にシステムの IP_FORWARD 設定項目をチェックします。現在のシステムの IP_FORWARD 機能が無効になっている場合は、IP_FORWARD 機能を一時的に有効にするのに役立ちます。ただし、一時的に有効になった IP_FORWARD 機能は、他のさまざまな理由で失敗します... この障害の具体的な原因を突き止める決定的な証拠はまだありませんが、ネットワーク サービスの再起動が原因であると真剣に疑っています。問題のあるサーバー ホストは、当社の R&D チームが開発している Web プロジェクトを実行しているため、機能の 1 つはネットワーク カードの IP アドレスを変更することです。ネットワーク カードの IP を変更した後、この機能は自動的に次のコマンドを呼び出してネットワーク サービスを再起動します。 systemctl でネットワークサービスを再起動します。 ネットワーク サービスを再起動すると、Docker デーモン サービスによって自動的に設定された一時的な IP_FORWARD 構成が無効になります。 また、プログラムはコマンドを直接呼び出すため、履歴コマンドに痕跡は残りません。 修復ソリューションは非常に簡単で、コマンド 1 行だけです。 エコー 'net.ipv4.ip_forward = 1' >> /usr/lib/sysctl.d/50-default.conf 実行が完了したら、サーバーを再起動するか、次のコマンドを使用してファイルから構成を読み込みます。 sysctl -p /usr/lib/sysctl.d/50-default.conf それでおしまい。 3. まとめ Docker デーモン サービスは、起動時に、今回問題を引き起こした IP_FORWARD 構成など、多くの構成項目を調整するのに役立ちます。 Docker デーモンは、Docker コンテナのデフォルトのネットワーク モード (ブリッジ モード) が各コンテナにプライベート IP を割り当てるため、 IP_FORWARD 機能を有効にします。コンテナが外部と通信する必要がある場合は、NAT が必要です。 NAT では IP_FORWARD 機能がサポートされている必要があります。そうでない場合、NAT は使用できません。これは、IP_FORWARD 機能が無効になっている場合、ブリッジ モードを使用するコンテナーに内部からも外部からもアクセスできない理由も説明しています。 ただし、Linux ではセキュリティ上の理由から、IP_FORWARD 機能はデフォルトで無効になっています。Docker デーモン サービスは起動時に IP_FORWARD 機能が有効になっているかどうかを確認します。有効になっていない場合、Docker デーモンはこの機能を一時的にサイレントに有効にします。ただし、一時的に有効になった IP_FORWARD 機能は永続化できず、他のコマンドの干渉により無効になります。 しかし、この出来事から私はちょっとした真実を学びました。問題が発生したときは、慌てず、経験に基づいて大胆な仮定を立て、それを検証して症状と根本原因の両方に対処することです。 要約する 上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に一定の参考学習価値を持つことを願っています。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM を応援していただきありがとうございます。 以下もご興味があるかもしれません:
|
>>: MySQLデータベースの増分バックアップのアイデアと方法
mysqlのrootアカウント、普段はlocalhostか127.0.0.1で接続しています。会社の...
目次MySQL Load Dataの多様な用途1. LOAD の基本的な背景2. 基本パラメータをロ...
数日前、CSS を使用して三角形の矢印を実装する方法について記事を書きました。 目的の効果は達成され...
この記事では、カレンダー機能を実装するためのVue.jsの具体的なコードを例として紹介します。具体的...
目次gzip 圧縮を使用する理由は何ですか? nginxはgzipを実装するgzip処理nginx ...
目次1. 準備Redisイメージを取得する2. Redis Sentinel マスタースレーブモード...
この記事では、参考までにタイマーを実装するためのVueの具体的なコードを紹介します。具体的な内容は次...
について最近、Vue を学習する過程で、基本的な知識の練習と強化を目的として、Qunar.com の...
1. ベクターマップベクター グラフィックスは直線と曲線を使用してグラフィックスを表します。これらの...
今はモバイルインターネットが急速に発展している時代です。スマートフォンやタブレットはますます普及し、...
このブログ投稿は、ブロガーが数日前に取り組んだプロジェクトで遭遇した困難についてです。これを学んだ後...
Web ページ ボックス モデルには 2 種類あります。 1: 標準 W3C ボックス モデル。2:...
MySQLはレプリケーションフィルターを動的に変更します今日遭遇した問題についてお話しします。今日は...
Linux の seq コマンドは、数字のリストを非常に高速に生成でき、使いやすく柔軟性に優れてい...
フォームは、get と post の 2 つのデータ転送方法を提供します。どちらもデータを送信する方...