यदि अपस्ट्रीम में होस्ट नहीं मिला है, तो सेटअप नगीने को क्रैश न करें


117

हमारे पास डॉकर में आम डोमेन के अंतर्गत कई रेल एप्लिकेशन हैं, और हम विशिष्ट एप्लिकेशन के लिए सीधे अनुरोधों के लिए nginx का उपयोग करते हैं।

our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar

कॉन्फ़िगरेशन इस तरह दिखता है:

upstream foo {
  server foo:3000;
}

upstream bar {
  server bar:3000;
}

# and about 10 more...

server {
  listen *:80 default_server;

  server_name our_dev_server.com;

  location /foo {
      # this is specific to asset management in rails dev
      rewrite ^/foo/assets(/.*)$ /assets/$1 break;
      rewrite ^/foo(/.*)$ /foo/$1 break;
      proxy_pass http://foo;
  }

  location /bar {
      rewrite ^/bar/assets(/.*)$ /assets/$1 break;
      rewrite ^/bar(/.*)$ /bar/$1 break;
      proxy_pass http://bar;
  }

  # and about 10 more...
}

यदि इनमें से एक ऐप शुरू नहीं हुआ है, तो nginx विफल रहता है और बंद हो जाता है:

host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6

हमें उन सभी की ज़रूरत नहीं है लेकिन नगनेक्स अन्यथा विफल हो जाते हैं। नंगेक्स को कैसे करें नजरअंदाज फेल अपस्ट्रीम?


1
क्या आप ऐप कंटेनरों को Nginx कंटेनरों के साथ जोड़ रहे हैं, या उन्हें एक दूसरे से अलग चला रहे हैं? यदि upstreamब्लॉक के भीतर मेजबान रनटाइम पर हल नहीं करता है, तो निगनेक्स उपरोक्त त्रुटि के साथ बाहर निकल जाएगा ...
जस्टिन

1
यदि आप एक आईपी का उपयोग कर सकते हैं तो यह स्टार्ट-अप ठीक है। क्या आपके मामले में resolver( nginx.org/en/docs/http/ngx_http_core_module.html#resolver ) काम कर रहा है?
जस्टिन

@ जस्टिन में हमारे पास अलग-अलग कंटेनर में प्रत्येक ऐप है, नगेंक्स भी। उन्हें डॉक के साथ लिंक करें
मोरोज़ोव

@ जस्टिन स्टार्टअप ऑर्डर ठीक है, नगनेक्स अन्य ऐप के बाद शुरू होता है। हम सिर्फ उनमें से कुछ को चलाना चाहते हैं :)
मोरजोव

1
मुझे एक समान सेटअप मिला है (एप्लिकेशन कंटेनर (नों) के साथ Nginx कंटेनर) । हमने एक Nginx छवि बनाई जिसमें एक proxy.shस्क्रिप्ट शामिल है जो पर्यावरण चर पढ़ता है और गतिशील रूप से upstreamप्रत्येक के लिए प्रविष्टियां जोड़ता है , फिर Nginx शुरू करता है। यह उस समय बहुत अच्छा काम करता है जब हम अपने प्रॉक्सी कंटेनर चलाते हैं, हम रनटाइम के दौरान आवश्यक अपस्ट्रीम में पास हो सकते हैं। आप लॉन्च के समय कुछ अपस्ट्रीम को सक्षम / अक्षम करने के लिए कुछ ऐसा ही कर सकते थे (या मेरे सेटअप की तरह रनटाइम के दौरान ज़रूरी
जस्टिन

जवाबों:


90
  1. यदि आप एक स्थिर आईपी का उपयोग कर सकते हैं, तो बस इसका उपयोग करें, यह स्टार्टअप होगा और 503यदि यह प्रतिक्रिया नहीं देता है तो बस वापस लौटें ।

  2. resolverकुछ को इंगित करने के लिए निर्देश का उपयोग करें जो मेजबान को हल कर सकता है, भले ही वह वर्तमान में हो या नहीं।

  3. locationयदि आप ऊपर नहीं कर सकते हैं तो इसे स्तर पर हल करें , (यह Nginx को शुरू / चलाने की अनुमति देगा) :

    location /foo {
      resolver 127.0.0.1 valid=30s;
      # or some other DNS (you company/internal DNS server)
      #resolver 8.8.8.8 valid=30s;
      set $upstream_foo foo;
      proxy_pass http://$upstream_foo:80;
    }
    
    location /bar {
      resolver 127.0.0.1 valid=30s;
      # or some other DNS (you company/internal DNS server)
      #resolver 8.8.8.8 valid=30s;
      set $upstream_bar foo;
      proxy_pass http://$upstream_bar:80;
    }
    

1
आपका विकल्प 3 मेरे लिए बहुत अच्छा काम करता है। यदि मैं एक रिज़ॉल्वर निर्दिष्ट नहीं करता हूं, तो क्या आप जानते हैं कि नगनेक्स आईपी को कितने समय में हल करेगा?
रिले लार्क

14
धन्यवाद! बस एक चर का उपयोग करते हुए इसके बारे में स्मार्ट होने से nginx रखने के लिए लगता है
ब्लेंका

1
मैंने पाया कि एक location ~ ^/foo/(.*)$ { proxy_pass http://foo/$1; }
रेगीक्स

2
टीसीपी प्रॉक्सी के लिए यह कैसे काम करता है? लगता है कि tcp प्रॉक्सी के लिए विकल्प 3 को आज़माने का कोई तरीका नहीं है।
krish7919

1
@ नॉर्क्स में उन प्रकार की त्रुटियों को लगभग हमेशा याद रखने से संबंधित होता है ";" लाइन के अंत में साइन इन करें :)
स्टीवबी

18

मेरे लिए, @ जस्टिन / @ duskwuff के उत्तर के विकल्प 3 ने समस्या को हल कर दिया, लेकिन मुझे रिज़ॉल्वर आईपी को 127.0.0.11 (डॉकर के DNS सर्वर) में बदलना पड़ा :

location /foo {
  resolver 127.0.0.11 valid=30s;
  set $upstream_foo foo;
  proxy_pass http://$upstream_foo:80;
}

location /bar {
  resolver 127.0.0.11 valid=30s;
  set $upstream_bar foo;
  proxy_pass http://$upstream_bar:80;
}

लेकिन जैसा कि @ जस्टिन / @ duskwuff उल्लेख किया गया है, आप किसी अन्य बाहरी DNS सर्वर का उपयोग कर सकते हैं।


15

उपयोग upstreamकरने का मुख्य लाभ सर्वर के एक समूह को परिभाषित करना है जो विभिन्न बंदरगाहों पर सुन सकते हैं और उनके बीच लोड-संतुलन और विफलता को कॉन्फ़िगर कर सकते हैं

आपके मामले में आप केवल 1 प्राथमिक सर्वर को अपस्ट्रीम में परिभाषित कर रहे हैं, इसलिए इसे ऊपर होना चाहिए

इसके बजाय, अपने proxy_pass(तों) के लिए चर का उपयोग करें और संभव त्रुटियों (404s, 503s) को संभालने के लिए याद रखें जो आपको एक लक्ष्य सर्वर के डाउन होने पर प्राप्त हो सकते हैं।


1
> इसके बजाय, अपने प्रॉक्सी_पास (तों) के लिए चर का उपयोग करें और संभव त्रुटियों (404s, 503s) को संभालने के लिए याद रखें जो आपको लक्ष्य सर्वर के डाउन होने पर प्राप्त हो सकते हैं। क्या आप ऐसा करने के बारे में विस्तार से बता सकते हैं? अगर मैं करता हूं set $variable http://fooऔर proxy_pass $variableफू "अपस्ट्रीम" (आपके द्वारा उल्लिखित फायदे रखने के लिए) रखता हूं, तो मैं अभी भी ओपी द्वारा उल्लिखित मुद्दे को मार रहा हूं।
टिबर वास

6
जैसा कि आप अन्य उदाहरणों में देख सकते हैं, यह होगा set $variable fooऔरproxy_pass http://$variable
danielgpm

2
@danielgpm जैसा कि आपने कहा, प्रॉक्सी_पास के लिए वैरिएबल का उपयोग पूरी तरह से काम करता है और मेरी समस्या को हल करता है। यदि आप अपने उत्तर को अपडेट कर सकते हैं और उदाहरण के रूप में उल्लेख कर सकते हैं तो यह दूसरों की मदद करेगा
Nitb

3
क्या होगा यदि मेरे पास एक से अधिक हैं, और मैं उन लोगों को अनदेखा करना चाहता हूं जिन्हें हल नहीं किया जा सकता है?
तालबेस

0

मैं था, क्योंकि मेरे मेजबान के हिस्से का उपयोग कर मैप किया जा रहा था वही "होस्ट नहीं मिला" मुद्दा $uriबजाय $request_uri:

proxy_pass http://one-api-service.$kubernetes:8091/auth;

और जब अनुरोध को अधीनस्थ में बदल दिया गया, तो $uriइसका प्रारंभिक मूल्य खो गया। मेरी समस्या $request_uriको $uriहल करने के बजाय उपयोग करने के लिए मैपिंग बदलना :

map $request_uri $kubernetes {
    # ...
}

-8

आप --linkविकल्प का उपयोग नहीं कर सकते हैं , इसके बजाय आप पोर्ट मैपिंग का उपयोग कर सकते हैं और नगीन को होस्ट पते पर बाँध सकते हैं।

उदाहरण: -p 180:80विकल्प के साथ अपना पहला डॉकटर कंटेनर चलाएं , विकल्प के साथ दूसरा कंटेनर -p 280:80

Nginx चलाएं और प्रॉक्सी के लिए ये पते निर्धारित करें:

proxy_pass http://192.168.1.20:180/; # first container
proxy_pass http://192.168.1.20:280/; # second container
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.