डॉकर - नग्नेक्स और php-fpm को अलग-अलग स्केलिंग करना


11

मैं डॉकटर और डॉकटर-कम्पोज़ के साथ खेल रहा हूं और एक सवाल है।

वर्तमान में मेरा docker-compose.yml कुछ इस प्रकार है:

app:
    image: myname/php-app
    volumes:
        - /var/www
    environment:
        <SYMFONY_ENVIRONMENT>: dev

web:
    image: myname/nginx
    ports:
        - 80
    links:
        - app
    volumes_from:
        - app

ऐप में पोर्ट 9000 पर php-fpm और मेरा एप्लीकेशन कोड है। वेब कुछ बिट्स कॉन्फिग के साथ nginx है।

यह कार्य करता है कि मैं यह अपेक्षा कैसे करूँ कि nginx को php-fpm से जोड़ने के लिए मेरे पास यह पंक्ति है:

fastcgi_pass    app:9000;

मैं इसे प्रभावी ढंग से कैसे माप सकता हूं? अगर मैं चाहता हूं, उदाहरण के लिए, एक नगीन कंटेनर चल रहा है, लेकिन तीन ऐप कंटेनर चल रहे हैं, तो मैं निश्चित रूप से तीन php-fpm उदाहरण है, जो सभी पोर्ट 9000 पर सुनने की कोशिश कर रहे हैं।

मैं एक अलग बंदरगाह पर प्रत्येक php-fpm उदाहरण कैसे दे सकता हूं, लेकिन फिर भी पता है कि वे किसी भी समय मेरे nginx config में कहां हैं?

क्या मैं गलत तरीका अपना रहा हूं?

धन्यवाद!

जवाबों:


5

एक उपाय यह है कि आप अपने docker-compose फ़ाइल में अतिरिक्त php-fpm इंस्टेंस जोड़ें और फिर उनके बीच लोड-बैलेंस करने के लिए अन्य उत्तरों में उल्लिखित nginx अपस्ट्रीम का उपयोग करें। यह इस उदाहरण में किया गया है docker-compose repo: https://github.com/iamyojimbo/docker-nginx-php-fpm/blob/master/nginx/nginx.conf##137

upstream php {
    #If there's no directive here, then use round_robin.
    #least_conn;
    server dockernginxphpfpm_php1_1:9000;
    server dockernginxphpfpm_php2_1:9000;
    server dockernginxphpfpm_php3_1:9000;
}

यह वास्तव में आदर्श नहीं है क्योंकि जब आप ऊपर या नीचे स्केल करना चाहते हैं तो इसे nginx config और docker-compose.yml को बदलने की आवश्यकता होगी।

ध्यान दें कि 9000 पोर्ट कंटेनर के लिए आंतरिक है और आपका वास्तविक होस्ट नहीं है, इसलिए इससे कोई फर्क नहीं पड़ता कि आपके पास पोर्ट के लिए कई php-fpm कंटेनर हैं।

डॉकर ने टुटम को इस गिरावट का अधिग्रहण किया। उनके पास एक समाधान है जो एक HAProxy कंटेनर को अपने एपीआई के साथ लोड-बैलेंसर कॉन्फिग को स्वचालित रूप से समायोजित करने के लिए चलाता है जो इसे लोड-बैलेंसिंग है। यह एक अच्छा उपाय है। फिर नग्नेक्स लोड-बैलेंसर को सौंपे गए होस्टनाम को इंगित करता है। शायद डॉकटर आगे इस प्रकार के समाधान को टुटम अधिग्रहण के बाद अपने उपकरणों में एकीकृत करेगा। इसके बारे में एक लेख यहाँ है: https://web.archive.org/web/20160628133445/https://support.tutum.co/support/solutions/articles/5000050235-load-balancing-a-web-service

टुटम वर्तमान में एक सशुल्क सेवा है। Rancher एक ओपन-सोर्स प्रोजेक्ट है जो एक समान लोड-संतुलन सुविधा प्रदान करता है। उनके पास एक "रंचर-कम्पोज़.इमल" भी है जो डॉकटर-कम्पोज़.इमल में सेवाओं की स्थापना के लोड-संतुलन और स्केलिंग को परिभाषित कर सकता है। http://rancher.com/the-magical-moment-when-container-load-balancing-meets-service-discovery/ http://docs.rancher.com/rancher/concepts/#load-balancer

UPDATE 2017/03/06: मैंने इंटरलॉक नाम की एक परियोजना का उपयोग किया है जो डॉकटर के साथ काम करने के लिए स्वतः nginx config को अद्यतन करता है और इसे पुनरारंभ करता है। इसके अलावा @ iwaseatenbyagrue का उत्तर देखें जिसमें अतिरिक्त दृष्टिकोण हैं।


1

आप कई बैकेंड को परिभाषित करने के लिए एक अपस्ट्रीम का उपयोग कर सकते हैं, जैसा कि यहां वर्णित है:

/programming/5467921/how-to-use-fastcgi-next-upstream-in-nginx

जब भी नई बैकएंड मर जाती है, तो आप कॉन्फिग्रेशन को अपडेट करना चाहते हैं / जैसे कुछ के साथ सेवा में आते हैं:

https://github.com/kelseyhightower/confd


0

उस स्थिति में जहां आपके Nginx और php-fpm कंटेनर एक ही होस्ट पर हैं, आप Nginx कंटेनर द्वारा उपयोग किए जाने वाले होस्ट पर एक छोटे से dnsmasq उदाहरण को कॉन्फ़िगर कर सकते हैं , और कंटेनर के IP पते को स्वचालित रूप से DNS रिकॉर्ड को अपडेट करने के लिए एक स्क्रिप्ट चलाते हैं। बदला हुआ।

मैंने ऐसा करने के लिए एक छोटी सी स्क्रिप्ट लिखी है (नीचे चिपकाया गया है), जो स्वचालित रूप से DNS रिकॉर्ड को अपडेट करता है जिसमें कंटेनरों के नाम के समान नाम है और उन्हें कंटेनरों के आईपी पते पर इंगित करता है:

#!/bin/bash

# 10 seconds interval time by default
INTERVAL=${INTERVAL:-10}

# dnsmasq config directory
DNSMASQ_CONFIG=${DNSMASQ_CONFIG:-.}

# commands used in this script
DOCKER=${DOCKER:-docker}
SLEEP=${SLEEP:-sleep}
TAIL=${TAIL:-tail}

declare -A service_map

while true
do
    changed=false
    while read line
    do
        name=${line##* }
        ip=$(${DOCKER} inspect --format '{{.NetworkSettings.IPAddress}}' $name)
        if [ -z ${service_map[$name]} ] || [ ${service_map[$name]} != $ip ] # IP addr changed
        then
            service_map[$name]=$ip
            # write to file
            echo $name has a new IP Address $ip >&2
            echo "host-record=$name,$ip"  > "${DNSMASQ_CONFIG}/docker-$name"
            changed=true
        fi
    done < <(${DOCKER} ps | ${TAIL} -n +2)

    # a change of IP address occured, restart dnsmasq
    if [ $changed = true ]
    then
        systemctl restart dnsmasq
    fi

    ${SLEEP} $INTERVAL
done

फिर, अपने nginx कंटेनर को प्रारंभ करें --dns host-ip-address, जहां host-ip-addressइंटरफ़ेस पर होस्ट का आईपी पता है docker0

आपके Nginx कॉन्फ़िगरेशन को गतिशील रूप से नामों को हल करना चाहिए:

server {
  resolver host-ip-address;
  listen 80;
  server_name @server_name@;
  root /var/www/@root@;
  index index.html index.htm index.php;

  location ~ ^(.+?\.php)(/.*)?$ {
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$1;
    set $backend "@fastcgi_server@";
    fastcgi_pass $backend;
  }
}

संदर्भ:

यदि आपका नग्नेक्स और php-fpm अलग-अलग होस्ट पर हैं, तो आप @ smaj का उत्तर आज़मा सकते हैं।


0

एक और तरीका यह हो सकता है कि कौंसुल-टेम्प्लेट जैसी किसी चीज़ पर गौर करें ।

और हां, कुछ बिंदु पर, कुबेरनेट्स का उल्लेख करने की आवश्यकता हो सकती है।

हालाँकि, आप थोड़ा और अधिक 'बिट्स ऑफ़ स्ट्रिंग और डक्ट टेप' दृष्टिकोण पर विचार कर सकते हैं जो उपभोग करने वाले ईवेंट आपके लिए क्या कर सकते हैं ( docker events --since 0एक त्वरित नमूने के लिए चलाएं )।

इन घटनाओं को देखने के लिए एक स्क्रिप्ट का होना बहुत ही मामूली होगा (ध्यान में रखते हुए कई क्लाइंट पैकेज उपलब्ध हैं, जिसमें अजगर, गो, आदि शामिल हैं), एक कॉन्फिग फाइल में संशोधन, और नग्नेक्स को पुनः लोड करना (अर्थात कंसुल-टेम्प्लेट दृष्टिकोण का उपयोग करना,) लेकिन कंसुल की आवश्यकता के बिना)।

अपने मूल आधार पर वापस जाने के लिए, हालाँकि: जब तक आपके php-fpm कंटेनरों को अपने स्वयं के नेटवर्क से शुरू किया जाता है (अर्थात किसी अन्य कंटेनर, जैसे कि नगनेक्स एक को साझा नहीं करना), तब आपके पास पोर्ट पर सुनने वाले कई कंटेनर हो सकते हैं 9000 जैसा आप चाहते हैं - जैसा कि उनके पास प्रति कंटेनर आईपी है, पोर्ट 'क्लैशिंग' के साथ कोई समस्या नहीं है।

आप इसे कैसे मापेंगे, यह संभावना पर निर्भर करेगा कि आपका अंतिम लक्ष्य / उपयोग-मामला क्या है, लेकिन एक चीज जिस पर आप विचार कर सकते हैं वह है नैप्रोक्स और आपके php-fpm नोड्स के बीच HAproxy को रखना। एक चीज़ जो आपको करने की अनुमति दे सकती है, वह है बस docker networkअपने php-fpm सर्वरों (यानी 172.18.0.0/24) के लिए एक सीमा (और संभवतः बनाएं ), और उस सीमा के भीतर किसी भी IP का उपयोग करने के लिए एक बैकएंड के रूप में उपयोग करने के लिए कॉन्फ़िगर किया गया है। । चूंकि HAproxy के पास स्वास्थ्य जांच है, यह जल्दी से पहचान सकता है कि कौन से पते लाइव हैं, और उनका उपयोग करें।

इस बारे में चर्चा के लिए /programming/1358198/nginx-removing-upstream-servers-from-pool देखें कि कैसे nginx बनाम haproxy अपस्ट्रीम के साथ काम करता है।

जब तक आप इसके लिए समर्पित डॉकटर नेटवर्क का उपयोग नहीं कर रहे थे, आपको अपने php-fpm नोड्स के लिए कुछ मैन्युअल IP प्रबंधन करने की आवश्यकता हो सकती है।


0

हालाँकि यह पोस्ट 2015 की है और मुझे लगता है कि मैं नेक्रोइंग (खेद समुदाय) हूँ, मुझे लगता है कि इस मामले में जोड़ना मूल्यवान है:

आजकल (और जब से कुबेरनेट्स का उल्लेख किया गया था) जब आप डोकर के साथ काम कर रहे हैं तो आप इस समस्या को हल करने के लिए कुबेरनेट्स या डोकर स्वार्म का उपयोग बहुत आसानी से कर सकते हैं। दोनों ऑर्केस्ट्रेटर आपके डॉक नोड्स (उस पर डॉकर के साथ एक नोड = एक सर्वर) में ले जाएंगे और आप उन्हें सेवाएं प्रदान कर सकते हैं और वे ओवरले नेटवर्क का उपयोग करके आपके लिए पोर्ट चुनौतियों का प्रबंधन करेंगे।

जैसा कि मैं डोकर झुंड में अधिक निपुण हूं, इस तरह से आप इस समस्या से निपटने के लिए ऐसा करेंगे (यह मानते हुए कि आपके पास एक डॉकटर नोड है):

झुंड को प्रारंभिक करें:

docker swarm init

अपने प्रोजेक्ट रूट में सी.डी.

cd some/project/root

अपने docker-compose.yml से एक झुंड स्टैक बनाएं (docker-compose का उपयोग करने के बजाय):

docker stack deploy -c docker-compose.yml myApp

यह "myApp" नामक docker swarm सर्विस स्टैक बनाएगा और आपके लिए पोर्ट का प्रबंधन करेगा। इसका मतलब है: आपको केवल अपने docker-compose फ़ाइल में अपनी php-fpm सेवा के लिए एक "port: 9000: 9000" जोड़ना होगा और फिर आप php-fpm सेवा को स्केल कर सकते हैं, 3 उदाहरणों के लिए, जबकि झुंड बिना किसी अतिरिक्त कार्य के तीन उदाहरणों के बीच अनुरोधों को ऑटो-जादुई रूप से लोड-बैलेंस करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.