Docker - menskalakan nginx dan php-fpm secara terpisah

11

Saya telah bermain-main dengan buruh pelabuhan dan buruh pelabuhan dan memiliki pertanyaan.

Saat ini docker-compose.yml saya terlihat seperti ini:

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

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

Aplikasi berisi php-fpm pada port 9000 dan kode aplikasi saya. Web adalah nginx dengan beberapa bit konfigurasi.

Ini berfungsi bagaimana saya harapkan tetapi untuk menghubungkan nginx ke php-fpm saya memiliki baris ini:

fastcgi_pass    app:9000;

Bagaimana saya bisa mengukur skala ini secara efektif? Jika saya ingin, misalnya, untuk menjalankan satu wadah nginx tetapi tiga wadah aplikasi berjalan maka saya pasti akan memiliki tiga instance php-fpm yang semuanya mencoba mendengarkan pada port 9000.

Bagaimana saya bisa membuat setiap instance php-fpm pada port yang berbeda tetapi masih tahu di mana mereka berada di konfigurasi nginx saya pada waktu tertentu?

Apakah saya mengambil pendekatan yang salah?

Terima kasih!

JimBlizz
sumber

Jawaban:

5

Salah satu solusinya adalah menambahkan instance php-fpm tambahan ke file komposisi buruh pelabuhan Anda dan kemudian menggunakan nginx hulu seperti yang disebutkan dalam jawaban lain untuk memuat-menyeimbangkan di antara mereka. Ini dilakukan dalam contoh ini repo buruh pelabuhan: 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;
}

Ini tidak benar-benar ideal karena akan membutuhkan mengubah nginx config dan docker-compose.yml ketika Anda ingin meningkatkan atau menurunkan.

Perhatikan bahwa port 9000 adalah internal ke wadah dan bukan host Anda yang sebenarnya, jadi tidak masalah bahwa Anda memiliki beberapa kontainer php-fpm di port 9000.

Docker mengakuisisi Tutum musim gugur ini. Mereka memiliki solusi yang menggabungkan wadah HAProxy dengan api mereka untuk secara otomatis menyesuaikan konfigurasi load-balancer ke kontainer yang sedang berjalan itu adalah load-balancing. Itu solusi yang bagus. Kemudian nginx menunjuk ke nama host yang ditugaskan ke load-balancer. Mungkin Docker akan lebih lanjut mengintegrasikan solusi jenis ini ke dalam alat mereka setelah akuisisi Tutum. Ada sebuah artikel di sini: https://web.archive.org/web/20160628133445/https://support.tutum.co/support/solutions/articles/5000050235-load-balancing-a-web-service

Tutum saat ini adalah layanan berbayar. Rancher adalah proyek open-source yang menyediakan fitur load-balancing serupa. Mereka juga memiliki "rancher-compose.yml" yang dapat menentukan penyeimbangan beban dan penskalaan pengaturan layanan di 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: Saya telah menggunakan proyek yang disebut interlock yang bekerja dengan Docker untuk secara otomatis memperbarui nginx config dan memulai kembali. Juga lihat jawaban @ iwaseatenbyagrue yang memiliki pendekatan tambahan.

rmarscher
sumber
0

Jika wadah Nginx dan php-fpm Anda berada di host yang sama, Anda bisa mengonfigurasi instance dnsmasq kecil di host yang akan digunakan oleh wadah Nginx, dan menjalankan skrip untuk secara otomatis memperbarui catatan DNS ketika alamat IP kontener memiliki berubah.

Saya telah menulis skrip kecil untuk melakukan ini (disisipkan di bawah), yang secara otomatis memperbarui catatan DNS yang memiliki nama yang sama dengan nama kontainer dan mengarahkannya ke alamat IP kontainer:

#!/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

Kemudian, mulai wadah nginx Anda dengan --dns host-ip-address, di mana host-ip-addressalamat IP host pada antarmuka docker0.

Konfigurasi Nginx Anda harus menyelesaikan nama secara dinamis:

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;
  }
}

Referensi:

Jika nginx dan php-fpm Anda berada di host yang berbeda, Anda dapat mencoba jawaban @ smaj.

xuhdev
sumber
0

Pendekatan lain mungkin untuk melihat sesuatu seperti konsul-templat .

Dan tentu saja, pada titik tertentu, Kubernetes mungkin perlu disebutkan.

Namun, Anda dapat mempertimbangkan pendekatan sedikit lebih 'string dan lakban' dengan melihat apa yang bisa dilakukan oleh peristiwa buruh pelabuhan (menjalankan docker events --since 0sampel cepat).

Akan sangat sepele untuk memiliki skrip yang melihat peristiwa ini (mengingat ada beberapa paket klien yang tersedia, termasuk untuk python, go, dll), mengubah file konfigurasi, dan memuat ulang nginx (yaitu menggunakan pendekatan konsul-templat, tetapi tanpa perlu konsul).

Namun, untuk kembali ke premis asli Anda: selama kontainer php-fpm Anda dimulai dengan jaringan mereka sendiri (mis. Tidak membagikannya dari wadah lain, seperti nginx), maka Anda dapat memiliki banyak wadah mendengarkan di pelabuhan 9000 seperti yang Anda inginkan - karena mereka memiliki IP per-kontainer, tidak ada masalah dengan port 'clashing'.

Bagaimana Anda mengukur skala ini kemungkinan akan tergantung pada apa tujuan akhir Anda / use-case, tetapi satu hal yang mungkin Anda pertimbangkan adalah menempatkan HAproxy antara nginx dan node php-fpm Anda. Satu hal yang dapat Anda lakukan adalah mencalonkan rentang (dan mungkin membuat a docker network) untuk server php-fpm Anda (yaitu 172.18.0.0/24), dan mengonfigurasi HAproxy untuk mencoba dan menggunakan IP apa pun dalam rentang itu sebagai backend . Karena HAproxy memiliki pemeriksaan kesehatan, ia dapat dengan cepat mengidentifikasi alamat mana yang aktif, dan memanfaatkannya.

Lihat /programming/1358198/nginx-removing-upstream-servers-from-pool untuk diskusi tentang bagaimana nginx vs haproxy berurusan dengan upstreams.

Kecuali Anda menggunakan jaringan buruh pelabuhan khusus untuk ini, Anda mungkin perlu melakukan beberapa manajemen IP manual untuk node php-fpm Anda.

iwaseatenbyagrue
sumber
0

Meskipun posting ini dari tahun 2015 dan saya merasa saya necroing (komunitas maaf), saya merasa sangat berharga untuk menambahkan pada saat ini:

Saat ini (dan karena Kubernetes disebutkan) ketika Anda bekerja dengan Docker, Anda dapat menggunakan Kubernetes atau Docker Swarm dengan sangat mudah untuk menyelesaikan masalah ini. Kedua orkestra akan mengambil node docker Anda (satu node = satu server dengan Docker di atasnya) dan Anda dapat menggunakan layanan untuk mereka dan mereka akan mengelola tantangan port untuk Anda menggunakan jaringan overlay.

Karena saya lebih berpengalaman dalam Docker Swarm, ini adalah bagaimana Anda akan melakukannya untuk mendekati masalah ini (dengan asumsi Anda memiliki satu node Docker):

Inisialisasi kawanan:

docker swarm init

cd ke root proyek Anda

cd some/project/root

buat tumpukan segerombolan dari buruh pelabuhan-compose.yml Anda (bukan menggunakan buruh pelabuhan-menulis):

docker stack deploy -c docker-compose.yml myApp

Ini akan membuat tumpukan layanan buruh pelabuhan yang disebut "myApp" dan akan mengelola port untuk Anda. Ini berarti: Anda hanya perlu menambahkan satu definisi "port: 9000: 9000" ke layanan php-fpm Anda di file komposisi docker dan kemudian Anda dapat meningkatkan layanan php-fpm, katakan ke 3 contoh, sementara swarm akan secara otomatis memuat-menyeimbangkan permintaan antara ketiga instance tanpa perlu kerja lebih lanjut.

Terburuk
sumber