Docker - ปรับ nginx และ php-fpm แยกกัน


11

ฉันได้เล่นกับนักเทียบท่าและนักเทียบท่าเขียนและมีคำถาม

ปัจจุบันนักเทียบท่าของฉัน-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

แอพมี php-fpm ที่พอร์ต 9000 และรหัสแอปพลิเคชันของฉัน เว็บคือ nginx ที่มีการตั้งค่าบิตน้อย

ฟังก์ชั่นนี้เป็นไปตามที่ฉันคาดหวังอย่างไรก็ตามเพื่อเชื่อมต่อ nginx กับ php-fpm ฉันมีบรรทัดนี้:

fastcgi_pass    app:9000;

ฉันจะขยายขนาดนี้ได้อย่างมีประสิทธิภาพได้อย่างไร ตัวอย่างเช่นถ้าฉันต้องการให้มีหนึ่ง nginx container ที่ทำงานอยู่ แต่สาม app container ที่ใช้งานอยู่ผมจะมีอินสแตนซ์ php-fpm สามตัวที่พยายามฟังบนพอร์ต 9000

ฉันจะมีแต่ละอินสแตนซ์ php-fpm ในพอร์ตที่แตกต่างกัน แต่ยังคงรู้ว่าพวกเขาอยู่ในการกำหนดค่า nginx ของฉันในเวลาใดก็ตาม

ฉันใช้วิธีที่ผิดหรือเปล่า?

ขอบคุณ!

คำตอบ:


5

ทางออกหนึ่งคือการเพิ่มอินสแตนซ์ php-fpm เพิ่มเติมให้กับไฟล์นักเทียบท่าของคุณจากนั้นใช้ nginx upstream ดังที่กล่าวไว้ในคำตอบอื่น ๆ เพื่อปรับสมดุลระหว่างโหลด สิ่งนี้ทำได้ในตัวอย่าง repo docker-compose: https://github.com/iamyojimbo/docker-nginx-php-fpm/blob/master/nginx/nginx.conf#L137

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 และ docker-compose.yml เมื่อคุณต้องการขยายหรือลดขนาด

โปรดทราบว่าพอร์ต 9000 นั้นอยู่ภายในคอนเทนเนอร์ไม่ใช่โฮสต์จริงของคุณดังนั้นจึงไม่สำคัญว่าคุณจะมีคอนเทนเนอร์ php-fpm หลายพอร์ตในพอร์ต 9000

นักเทียบท่าซื้อ Tutum ในฤดูใบไม้ร่วงนี้ พวกเขามีโซลูชันที่รวมคอนเทนเนอร์ HAProxy กับ api ของพวกเขาเพื่อปรับการตั้งค่าโหลดบาลานเซอร์ให้เป็นคอนเทนเนอร์ที่ใช้งานโดยอัตโนมัติซึ่งเป็นโหลดบาลานซ์ นั่นเป็นทางออกที่ดี จากนั้น nginx ชี้ไปที่ชื่อโฮสต์ที่กำหนดให้กับ load-balancer บางทีนักเทียบท่าจะรวมโซลูชันประเภทนี้เข้ากับเครื่องมือของพวกเขาเพิ่มเติมหลังจากการซื้อ Tutum มีบทความเกี่ยวกับที่นี่: https://web.archive.org/web/20160628133445/https://support.tutum.co/support/solutions/articles/5000050235-load-balancing-a-web-service

Tutum ปัจจุบันเป็นบริการชำระเงิน Rancher เป็นโครงการโอเพนซอร์ซที่มีคุณสมบัติการทำโหลดบาลานซ์เหมือนกัน พวกเขายังมี "rancher-compose.yml" ซึ่งสามารถกำหนดสมดุลภาระและการปรับขนาดของการตั้งค่าบริการใน docker-compose.yml 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: ฉันเคยใช้โปรเจ็กต์ชื่อinterlockที่ทำงานร่วมกับ Docker เพื่ออัพเดทการกำหนดค่า nginx และรีสตาร์ทโดยอัตโนมัติ โปรดดูคำตอบของ @ iwaseatenbyagrue ซึ่งมีแนวทางเพิ่มเติม


1

คุณสามารถใช้อัพสตรีมเพื่อกำหนดแบ็กเอนด์หลาย ๆ ตัวตามที่อธิบายไว้ที่นี่:

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

นอกจากนี้คุณยังต้องการอัปเดตการกำหนดค่าเมื่อใดก็ตามที่แบ็กเอนด์ใหม่เข้ามา / ให้บริการด้วยบางสิ่งเช่น:

https://github.com/kelseyhightower/confd


0

ในกรณีที่คอนเทนเนอร์ Nginx และ php-fpm ของคุณอยู่ในโฮสต์เดียวกันคุณสามารถกำหนดค่าอินสแตนซ์dnsmasqขนาดเล็กบนโฮสต์ที่จะใช้งานโดยคอนเทนเนอร์ Nginx และเรียกใช้สคริปต์เพื่ออัปเดตระเบียน DNS โดยอัตโนมัติเมื่อที่อยู่ IP ของคอนเทนเนอร์มี การเปลี่ยนแปลง

ฉันได้เขียนสคริปต์ขนาดเล็กเพื่อทำสิ่งนี้ (วางด้านล่าง) ซึ่งอัปเดตระเบียน DNS โดยอัตโนมัติซึ่งมีชื่อเดียวกับชื่อคอนเทนเนอร์และชี้ไปยังที่อยู่ IP ของคอนเทนเนอร์:

#!/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มีอยู่ IP 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;
  }
}

อ้างอิง:

หาก nginx และ php-fpm ของคุณอยู่ในโฮสต์ที่แตกต่างกันคุณสามารถลอง @ smaj คำตอบของ


0

อีกวิธีหนึ่งที่อาจจะมีการมองเข้าไปในสิ่งที่ต้องการกงสุลแม่แบบ

และแน่นอนในบางประเด็นคูเบอร์เนตอาจต้องมีการพูดถึง

อย่างไรก็ตามคุณสามารถพิจารณาวิธีการ 'บิตของสตริงและเทปพันสาย' ได้อีกเล็กน้อยโดยดูว่ากิจกรรมนักเทียบท่าที่บริโภคได้ทำอะไรให้คุณได้บ้าง (เรียกใช้docker events --since 0สำหรับกลุ่มตัวอย่างอย่างรวดเร็ว)

มันจะมีเหตุผลเล็กน้อยที่จะให้สคริปต์ดูเหตุการณ์เหล่านี้ (โปรดจำไว้ว่ามีแพคเกจไคลเอนต์จำนวนมากที่มีอยู่รวมถึง python, go, etc), แก้ไขไฟล์ config และโหลด nginx (เช่นใช้วิธีกงสุล - เทมเพลต แต่ไม่จำเป็นต้องมีกงสุล)

หากต้องการกลับไปยังสถานที่ตั้งเดิมของคุณ: ตราบใดที่คอนเทนเนอร์ php-fpm ของคุณเริ่มต้นด้วยเครือข่ายของตนเอง (เช่นไม่แชร์ที่คอนเทนเนอร์อื่นเช่น nginx one) จากนั้นคุณสามารถมีคอนเทนเนอร์จำนวนมากที่รับฟังพอร์ต 9000 ตามที่คุณต้องการ - เนื่องจากมี IP ต่อคอนเทนเนอร์หนึ่งตัวไม่มีปัญหากับ 'การปะทะกัน' ของพอร์ต

วิธีที่คุณปรับขนาดสิ่งนี้จะขึ้นอยู่กับเป้าหมายสูงสุด / กรณีใช้งานของคุณ แต่สิ่งหนึ่งที่คุณอาจพิจารณาคือการวาง HAproxy ระหว่าง nginx และโหนด php-fpm ของคุณ สิ่งหนึ่งที่คุณสามารถทำได้คือการเสนอชื่อช่วง (และอาจสร้างdocker network) สำหรับเซิร์ฟเวอร์ php-fpm ของคุณ (เช่น 172.18.0.0/24) และมี HAproxy ที่กำหนดค่าให้ลองใช้ IP ใด ๆ ภายในช่วงนั้นเป็นแบ็กเอนด์ . เนื่องจาก HAproxy มีการตรวจสุขภาพจึงสามารถระบุที่อยู่ได้อย่างรวดเร็วและใช้ประโยชน์ได้

ดู/programming/1358198/nginx-removing-upstream-servers-from-poolสำหรับการสนทนาเกี่ยวกับวิธีที่ nginx vs haproxy จัดการกับ upstreams

หากคุณไม่ได้ใช้เครือข่ายนักเทียบท่าเฉพาะสำหรับสิ่งนี้คุณอาจต้องจัดการ IP ด้วยตนเองสำหรับโหนด php-fpm ของคุณ


0

แม้ว่าโพสต์นี้มาจากปี 2015 และฉันรู้สึกว่าฉันกำลังทำลายล้าง (ชุมชนขออภัย) ฉันรู้สึกว่ามันมีประโยชน์ที่จะเพิ่มในเวลานี้:

ทุกวันนี้ (และตั้งแต่มีการกล่าวถึง Kubernetes) เมื่อคุณทำงานกับ Docker คุณสามารถใช้ Kubernetes หรือ Docker Swarm ได้อย่างง่ายดายเพื่อแก้ปัญหานี้ orchestrators ทั้งสองจะใช้เวลาในโหนดนักเทียบท่าของคุณ (หนึ่งโหนด = เซิร์ฟเวอร์หนึ่งตัวที่มีตัวเชื่อมต่อ) และคุณสามารถปรับใช้บริการกับพวกเขาและพวกเขาจะจัดการกับความท้าทายพอร์ตสำหรับคุณโดยใช้เครือข่ายโอเวอร์เลย์

เมื่อฉันมีประสบการณ์มากขึ้นใน Docker Swarm นี่คือวิธีที่คุณจะทำเพื่อแก้ไขปัญหานี้ (สมมติว่าคุณมีโหนด Docker เดียว):

เริ่มต้นฝูง:

docker swarm init

cd ลงในรูทโปรเจ็กต์ของคุณ

cd some/project/root

สร้างสแต็กฝูงจาก docker-compose.yml ของคุณ (แทนที่จะใช้นักเทียบท่าประกอบ):

docker stack deploy -c docker-compose.yml myApp

สิ่งนี้จะสร้างสแต็คบริการกลุ่มที่เรียกว่า "myApp" และจะจัดการพอร์ตให้คุณ ซึ่งหมายความว่า: คุณต้องเพิ่ม "พอร์ต: 9000: 9000" เพียงหนึ่งคำนิยามในบริการ php-fpm ของคุณในไฟล์นักเทียบท่าของคุณจากนั้นคุณสามารถขยายบริการ php-fpm พูดถึง 3 อินสแตนซ์ในขณะที่ฝูง โหลดบาลานซ์ร้องขออย่างอัตโนมัติโดยอัตโนมัติระหว่างสามอินสแตนซ์โดยไม่จำเป็นต้องทำงานเพิ่มเติมใด ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.