紹介する
libevent
私はウィジェットを使用してlibevhtp
http通信用のサーバーソケットを作成する独自のアプリケーションを開発しています。- 私は
Dockerfile
このアプリケーションをドッカーイメージに配置するプログラムを書いています。
結果Dockerイメージはデフォルトでアプリケーションを実行し、イメージを実行するとテストした他のマシン(ubuntu 20.04/22.04)で正常に動作します。
docker run --rm -p 8080:8080 -t mytag
- 同じネットワーク内でこのコンピュータのポート8080に接続できます。
docker exec -ti runningcontainer bash
実行中のコンテナを表示して、netstat -pntl
アプリケーションがポート8080でリッスンしていることを確認できます。
質問
私のラップトップではそうではありません。私は他のサーバーと同じようにUbuntuを実行しません。私はマンジャロにいます。しかし、これがどのように重要なのかわかりません。
- 私のラップトップで実行されているドッカーコンテナ内と実行中のアプリケーション内でリスニング
netstat -pntl
ソケットが表示されません。 - したがって、アプリケーションのポート8080に接続できません。 -
curl localhost:8080
返却Connection Refused
- マイコンピュータ(Dockerではない)でデフォルトでアプリケーションを実行すると、期待どおりに機能し、ポート8080にアクセスできます。
nc -l 0.0.0.0 9999
私のラップトップで実行されているDockerコンテナで実行すると、ソケットが開き、受信中であることが報告されnetstat
ます。nc 127.0.0.1 9999
コンテナ内から開いたソケットへの接続は期待どおりに機能します。--privileged
同じ結果でコンテナを実行してみましたが、動作しません。- 私はすべてのドッカーイメージ、コンテナ、ネットワークをトリミングし、私のコンピュータからすべてのドッカートレイルを削除して削除し、再インストールしましたが、動作に変化はありません。
結論として
何らかの理由でアプリケーションがDockerコンテナ内で実行されたときにリスニングソケットを開かないようです。実装ログにエラーは表示されません。注:エラーがあるか無視されるいくつかのエラーコードがあるかどうかを確認するために、実装をチェックしていません。
最も効率的な方法でこれを試してデバッグする方法を見つけるのに役立ちます。
私の次のステップは
- test.htmlファイルを提供するには、libevhtpを使用して小さなバイナリを作成し、dockerで実行してみてください。正常に動作する場合
- 犯人が見つかるまで誤動作するアプリケーションの一部を少しずつ無効にします。
2番目のステップは多くの作業が必要になるので、誰かが同様の問題を抱えているか、この作業を実行する前に試してみるいくつかのことを教えてくれるようにここにリンクします。
答え1
発見する
他のモジュールを有効にすると、初期化が常に失敗し、使用可能なファイル記述子がすべて使い果たされました。ソケットがバインドされるまでは何もありません。 dockerで使用しようとしたが、lsof
詰まって動作しない可能性が多すぎて早く諦めました。 (望むよりDockerでlsofを置き換える方法(LXCベースではなくデフォルト))
ファイル記述子制限の最後のインターネット検索:
# uname -r
5.15.106-1-MANJARO
# ulimit -n
1024
役に立つ答えは次のとおりです。https://stackoverflow.com/questions/24318543/私のためにこの問題を解決しました。
解決策:
--ulimit
パラメータを使用してDockerを実行する
docker run --rm -p 8080:8080 --ulimit nofile=262144:262144 -ti mytag:latest bash
修正する:
このスレッドによると:https://github.com/moby/moby/issues/44547
半永久的な解決策は、LimitNOFILE
ファイルの値をからに変更するようですinfinity
。システムがアップグレードされた後、この操作を繰り返す必要があるかもしれません。このスレッドには別の解決策が記載されています。1048576
/usr/lib/systemd/system/containerd.service
https://bbs.archlinux.org/viewtopic.php?id=285058/etc/docker/daemon.json
以下のように、dockerのデフォルトのulimitを設定するためにdocker設定ファイルを作成することをお勧めします。
{
"default-ulimits": {
"nofile": {
"Hard": 1048576,
"Name": "nofile",
"Soft": 1048576
}
}
}
次に、実行systemctl reload docker
して変更を適用します。