لدي تثبيت discourse قيد التشغيل (اثنان في الواقع، واحد في مرحلة الاختبار والآخر في الإنتاج، آلات افتراضية مختلفة وكل شيء). أنا أختبر على بيئة الاختبار. تم التثبيت عبر الدليل الرسمي.
حاليًا، تم نشر مكدس Grafana/Prometheus/Node Exporter عبر docker compose على نفس الجهاز الافتراضي حيث تم نشر تثبيت discourse بالفعل.
لمزيد من التعمق في الأمر، حاولت إنشاء مفتاح API من Discourse والوصول إليه باستخدام الاسم المضيف الداخلي، والاستجابة ليست 301، وهذا صحيح لأن كل طلب يجب إعادة توجيهه إلى https.
هل لديك المكون الإضافي Prometheus مثبتًا ومُمكّنًا؟ يجب أن يسمح بطلبات من عناوين خاصة، ولكن يمكنك محاولة تعيين متغير البيئة للسماح بالوصول من عنوان IP الذي تسحب منه.
نعم، بروميثيوس موجود على نفس الجهاز الظاهري ومُنشأ كحاوية دوكر. كل شيء يعمل (لدي مُصدِّرات أخرى مُنشأة أيضًا) ولكن لسبب ما، فإن إضافة بروميثيوس لـ Discourse، حتى لو كانت تعمل بوضوح، لا تقبل الطلبات.
عندما تقول متغير البيئة، هل تقصد البيئة في ملف app.yaml الخاص بـ Discourse؟
172.20.0.3 هو عنوان IP الداخلي الحالي الذي سيحصل عليه بروميثيوس على شبكة دوكر الافتراضية التي يتصل بها Discourse أيضًا.
لقد حاولت بالفعل استخدام عنوان IP الخارجي الذي تشترك فيه جميع الحاويات على أي حال (عنوان IP الثابت للجهاز الظاهري) ولكن نظرًا لأنها في نفس الشبكة، فعندما يحاول أحدهم الوصول إلى الآخر، فإنه يفعل ذلك عبر عنوان IP الداخلي.
هل يجب أن يكون ./launcher restart app كافيًا لالتقاط متغيرات البيئة؟
في هذه الحالة أحصل على:
Get "http://vmi1187507-app:80/metrics": dial tcp: lookup vmi1187507-app on 127.0.0.11:53: server misbehaving
vmi1187507-app هو اسم شبكة الحاوية في شبكتها. الاسم صحيح، يمكنني اختباره من حاوية بروميثيوس قيد التشغيل.
ليس لدي أي فكرة من أين يأتي 127.0.0.11:53 بصراحة
الرسالة هي نفسها إذا قمت بالتعليق على متغير البيئة.
/prometheus # wget http://vmi1229594-app:80/metrics
Connecting to vmi1229594-app:80 (172.20.0.2:80)
Connecting to [public URL] (172.67.69.84:443)
wget: note: TLS certificate validation not implemented
wget: server returned error: HTTP/1.1 404 Not Found
أخمن أن السبب هو إعادة التوجيه التلقائي من حاوية Discourse nginx؟
ما يحدث هو أنه يقوم بإعادة التوجيه إلى https لاسم النطاق العام وهو عنوان IP داخلي لـ Cloudflare وهذا بالطبع يطلب من أي طلب العودة.
الآن هذا ليس هو النقطة المهمة لأن هذا التوجيه لا ينبغي أن يحدث لمسار الرابط http://yourwebsite.com/metrics إذا كان قادمًا من عنوان IP داخلي وكنت أتوقع أن يقوم المكون الإضافي بالتعامل مع ذلك عن طريق إضافة تكوين nginx يضيف هذه القاعدة والتي يبدو أنها لا تحدث؟
هل يمكن لأحد مطوري Discourse التدخل؟ لا أريد أن أزعج الأشخاص عشوائيًا ويبدو غريبًا أن لا أحد قد أبلغ عن هذه المشكلة من قبل.
تعديل: قمت بإعادة البناء مع تحديد اسم مضيف ثابت لتكوين الشبكة لأنني لاحظت أنه في كل إعادة بناء يتم تعيين اسم عشوائي جديد للحاوية.
بعد ذلك، حاولت أيضًا تعيين مهمة prometheus للوصول إلى إصدار https للمقاييس ولكن المشكلة تعود إلى الخطوة الأولى:
/prometheus # wget https://discourse_app/metrics
Connecting to discourse_app (172.20.0.2:443)
wget: note: TLS certificate validation not implemented
Connecting to [public URL] (104.26.4.193:443)
wget: server returned error: HTTP/1.1 404 Not Found
هذا ليس مجال خبرتي، لكنني قمت بالبحث في المنشورات التي ابتلعها مؤقت الموضوع لمعرفة ما إذا كان أي منها ذا صلة، وربما وجدت هذه؟ (أعتذر إذا كنت مخطئًا تمامًا )
شكراً @JammyDodger ولكن للأسف لم تساعد تلك الموارد.
لديهم مشكلة مماثلة ولكنها مختلفة قليلاً لدرجة أنها لا تنطبق في هذه الحالة.
للتأكد، جربت ما اقترحه أحد تلك المواضيع (بالإضافة إلى @pfaffman) وتلاعبت بمتغير البيئة DISCOURSE_PROMETHEUS_TRUSTED_IP_ALLOWLIST_REGEX.
لقد اختبرت:
التعليق عليه
إضافته بقيمة IP داخلية
إضافته بقيمة IP خارجية
جربت أيضًا تغيير مهمة فحص Prometheus لمعالجة تثبيت Discourse كـ:
عنوان IP داخلي مباشر
اسم مضيف داخلي لـ Docker
عنوان IP خارجي مباشر
اسم نطاق عام
في كل حالة، جربت كلاً من http و https.
في جميع الحالات، أحصل على 404.
ما أتوقعه هو استجابة الصفحة الفعلية حيث أن الطلب قادم من عنوان IP داخلي.
ما قصده جاي هنا هو أنك تحتاج إلى استخدام اسم المضيف المُكوَّن (DISCOURSE_HOSTNAME في تعريف ملف .yml الخاص بالحاوية) بدلاً من أي اسم مضيف يحل إلى عنوان IP الصحيح.
هذا متعمد، بحيث لا يمكنك بسهولة عكس وكيل نسخة عامة من أي مكان، ولذلك يتم قبول اسم المضيف المُكوَّن فقط:
$ curl -I https://try.discourse.org/about.json
HTTP/2 200
server: nginx
date: Mon, 15 May 2023 16:25:05 GMT
content-type: application/json; charset=utf-8
[...]
# ما يلي يعادل إنشاء سجل DNS في
# try.somebogusreverseproxy.com يشير إلى نفس عنوان IP مثل try.discourse.org،
# ثم طلب https://try.somebogusreverseproxy.com/about.json
$ curl -H 'Host: try.somebogusreverseproxy.com' -I https://try.discourse.org/about.json
HTTP/2 404
cache-control: no-cache
content-length: 1427
content-type: text/html
cdck-proxy-id: app-router-tiehunter02.sea1
cdck-proxy-id: app-balancer-tieinterceptor1b.sea1
اكتشاف جيد ولكن إذا حاولت استهداف هذا المنفذ المحدد، أحصل على رسالة “تم رفض الاتصال”.
Get "http://discourse_app:9405/metrics": dial tcp 172.20.0.2:9405: connect: connection refused
تم الاختبار باستخدام wget من داخل حاوية prometheus أيضًا للتأكد.
/prometheus # ping discourse_app
PING discourse_app (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.223 ms
64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.270 ms
^C
--- discourse_app ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.223/0.246/0.270 ms
/prometheus # wget discourse_app:9405/metrics
Connecting to discourse_app:9405 (172.20.0.2:9405)
wget: can't connect to remote host (172.20.0.2): Connection refused
نعم، تم الاختبار باستخدام wget بدلاً من ذلك (حاوية prometheus هي busybox بسيطة) ولكن تم الوصول إلى المقاييس على أي حال.
إذًا، ما تقوله هو أنه يجب عليّ إيجاد طريقة لجعل الحاوية التي تشغل prometheus تحتوي على إدخال في /etc/hosts يحل… لقد فقدتك هناك آسف
ما قمت به هو إضافة حاوية Docker أخرى تحتوي ببساطة على nginx وتقديم تكوين وكيل أمامي يضيف الرأس Host إلى الطلبات التي يتلقاها. لا يكشف أي منفذ لذلك يمكن الوصول إليه فقط من خلال الشبكة الافتراضية الداخلية على أي حال.
للتوثيق فقط، لدي مستودع قمت فيه بإعداد كل ما هو ضروري.
هناك بعض القيم المكتوبة بشكل ثابت (مثل اسم النطاق المؤهل بالكامل لموقعنا الإلكتروني في ملف تكوين الوكيل الأمامي) والتي ستحتاج إلى تغيير في حالة رغبة شخص آخر في استخدامه، ولكن ربما يمكن أن يكون مفيدًا لشخص آخر هناك.
يتضمن كل شيء، من docker compose إلى تكوين nginx وتوفير grafana للموارد ولوحات المعلومات.
الربط بـ localhost يعني أنه لا يمكن الاتصال به إلا على عنوان IP المحلي، وهذا هو سبب فشل الاتصال بـ 172.20.0.2. هذا إجراء أمني لضمان عدم تعرضه عن طريق الخطأ لجمهور أوسع بكثير من المقصود.
إذا قمت بتعيين ملف تعريف الحاوية على:
DISCOURSE_PROMETHEUS_WEBSERVER_BIND: '*'
سيستمع على جميع عناوين IP وستتمكن من الاتصال به من حاوية أخرى.
هو أن حاوية nginx هذه تتحدث الآن إلى prometheus عبر عنوان IP localhost.
إذا لم تكن متأكدًا من عناوين IP أو المنافذ التي تستمع إليها الخدمات، يمكنك استخدام ss -ltp أو netstat -ltp (داخل الحاوية! الحزم الضرورية هي net-tools و iproute2 على التوالي) للنظر إليها. على سبيل المثال، لقد أعدت بناء حاوية باستخدام المكون الإضافي لـ prometheus ورأيت:
root@discourse-docker-app:/# ss -ltp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 127.0.0.1:3000 0.0.0.0:*
LISTEN 0 128 0.0.0.0:postgresql 0.0.0.0:*
LISTEN 0 128 0.0.0.0:https 0.0.0.0:* users:(("nginx",pid=555,fd=7))
LISTEN 0 128 127.0.0.1:9405 0.0.0.0:*
LISTEN 0 128 0.0.0.0:redis 0.0.0.0:*
LISTEN 0 128 0.0.0.0:http 0.0.0.0:* users:(("nginx",pid=555,fd=6))
LISTEN 0 128 [::]:postgresql [::]:*
LISTEN 0 128 [::]:https [::]:* users:(("nginx",pid=555,fd=8))
LISTEN 0 128 [::]:redis [::]:*
root@discourse-docker-app:/# curl http://172.17.0.2:9405/metrics
curl: (7) Failed to connect to 172.17.0.2 port 9405: Connection refused
root@discourse-docker-app:/# curl http://localhost:9405/metrics
# HELP discourse_collector_working Is the master process collector able to collect metrics
# TYPE discourse_collector_working gauge
discourse_collector_working 1
# HELP discourse_collector_rss total memory used by collector process
# TYPE discourse_collector_rss gauge
discourse_collector_rss 38178816
…
هذا هو خادم الأسماء الذي يرفض طلب البحث عن عنوان IP لـ vmi1187507-app. المنفذ 53 هو DNS.
هذا رائع يا مايكل، شكراً لك على تخصيص الوقت لكتابته.
سأقوم باختباره خلال عطلة نهاية الأسبوع حيث أنني قضيت بالفعل وقتاً طويلاً خلال أيام عملي لهذا الأسبوع
خلال محاولاتي، حاولت إضافة عنوان IP الداخلي الذي سيظهر منه الحاوية مع Prometheus على أنه يطلب المقاييس إلى DISCOURSE_PROMETHEUS_TRUSTED_IP_ALLOWLIST_REGEX ولكنه لم ينجح.
أنت تقترح DISCOURSE_PROMETHEUS_WEBSERVER_BIND. هل لي أن أسأل من أين حصلت عليه؟ أفترض أنه متغير بيئة آخر لإضافته إلى ملف app.yml، صحيح؟