Docker - chia tỷ lệ nginx và php-fpm riêng biệt


11

Tôi đã chơi xung quanh với docker và docker-compose và có một câu hỏi.

Hiện tại docker-compose.yml của tôi trông như thế này:

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

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

Ứng dụng chứa php-fpm trên cổng 9000 và mã ứng dụng của tôi. Web là nginx với một vài bit cấu hình.

Điều này hoạt động như thế nào tôi mong đợi nó tuy nhiên để kết nối nginx với php-fpm tôi có dòng này:

fastcgi_pass    app:9000;

Làm thế nào tôi có thể mở rộng quy mô này một cách hiệu quả? Ví dụ, nếu tôi muốn có một container nginx đang chạy nhưng ba container ứng dụng đang chạy thì tôi chắc chắn sẽ có ba phiên bản php-fpm tất cả đang cố gắng nghe trên cổng 9000.

Làm cách nào tôi có thể có mỗi phiên bản php-fpm trên một cổng khác nhau nhưng vẫn biết chúng ở đâu trong cấu hình nginx của tôi tại bất kỳ thời điểm nào?

Tôi đang dùng sai phương pháp?

Cảm ơn!

Câu trả lời:


5

Một giải pháp là thêm các phiên bản php-fpm bổ sung vào tệp soạn thảo docker của bạn và sau đó sử dụng ngược dòng nginx như được đề cập trong các câu trả lời khác để cân bằng tải giữa chúng. Điều này được thực hiện trong ví dụ này docker-compose repo: 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;
}

Điều này không thực sự lý tưởng bởi vì nó sẽ yêu cầu thay đổi cấu hình nginx và docker-compose.yml khi bạn muốn tăng hoặc giảm tỷ lệ.

Lưu ý rằng cổng 9000 là nội bộ của bộ chứa chứ không phải máy chủ thực tế của bạn, vì vậy việc bạn có nhiều bộ chứa php-fpm trên cổng 9000 không thành vấn đề.

Docker mua Tutum vào mùa thu này. Họ có một giải pháp kết hợp bộ chứa HAProxy với api của họ để tự động điều chỉnh cấu hình cân bằng tải cho các bộ chứa đang chạy mà nó đang cân bằng tải. Đó là một giải pháp tốt đẹp. Sau đó nginx trỏ đến tên máy chủ được gán cho bộ cân bằng tải. Có lẽ Docker sẽ tích hợp thêm loại giải pháp này vào các công cụ của họ sau khi mua lại Tutum. Có một bài viết về nó ở đây: https://web.archive.org/web/20160628133445/https://support.tutum.co/support/solutions/articles/5000050235-load-balANCE-a-web-service

Tutum hiện là một dịch vụ trả phí. Rancher là một dự án nguồn mở cung cấp tính năng cân bằng tải tương tự. Họ cũng có một "rancher-compose.yml" có thể xác định cân bằng tải và mở rộng quy mô của thiết lập dịch vụ trong docker-compose.yml. http://rancher.com/the-magical-moment-when-container-load-balANCE-meets-service-discovery/ http://docs.rancher.com/rancher/con accept / # load- balancer

CẬP NHẬT 2017/03/06: Tôi đã sử dụng một dự án có tên là interlock hoạt động với Docker để tự động cập nhật cấu hình nginx và khởi động lại nó. Đồng thời xem câu trả lời của @ iwaseatenbyagrue có cách tiếp cận bổ sung.



0

Trong trường hợp các thùng chứa Nginx và php-fpm của bạn trên cùng một máy chủ, bạn có thể định cấu hình một cá thể dnsmasq nhỏ trên máy chủ để sử dụng bởi bộ chứa Nginx và chạy tập lệnh để tự động cập nhật bản ghi DNS khi địa chỉ IP của bộ chứa đã thay đổi

Tôi đã viết một tập lệnh nhỏ để thực hiện việc này (dán bên dưới), tự động cập nhật bản ghi DNS có cùng tên với tên của bộ chứa và trỏ chúng đến địa chỉ IP của bộ chứa:

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

Sau đó, bắt đầu bộ chứa nginx của bạn với --dns host-ip-address, host-ip-addressđịa chỉ IP của máy chủ lưu trữ trên giao diện docker0.

Cấu hình Nginx của bạn sẽ giải quyết các tên động:

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

Người giới thiệu:

Nếu nginx và php-fpm của bạn ở trên các máy chủ khác nhau, bạn có thể thử câu trả lời của @ smaj.


0

Một cách tiếp cận khác có thể là xem xét một cái gì đó giống như mẫu lãnh sự .

Và tất nhiên, tại một số điểm, Kubernetes có thể cần được đề cập.

Tuy nhiên, bạn có thể xem xét cách tiếp cận nhiều hơn một chút 'bit của chuỗi và băng keo' bằng cách xem xét các sự kiện docker tiêu thụ có thể làm gì cho bạn (chạy docker events --since 0lấy mẫu nhanh).

Sẽ rất hợp lý khi có một kịch bản xem xét các sự kiện này (lưu ý rằng có một số gói khách hàng có sẵn, bao gồm cho python, go, v.v.), sửa đổi tệp cấu hình và tải lại nginx (tức là sử dụng phương pháp mẫu lãnh sự, nhưng không cần lãnh sự).

Tuy nhiên, để quay lại tiền đề ban đầu của bạn: miễn là các thùng chứa php-fpm của bạn được bắt đầu với mạng riêng của họ (nghĩa là không chia sẻ mạng của một container khác, chẳng hạn như nginx), thì bạn có thể có nhiều container nghe trên cổng 9000 như bạn muốn - vì họ có IP trên mỗi container, không có vấn đề gì với các cổng 'xung đột'.

Cách bạn mở rộng quy mô này có thể sẽ phụ thuộc vào mục tiêu / trường hợp sử dụng cuối cùng của bạn là gì, nhưng một điều bạn có thể cân nhắc là đặt HAproxy giữa các nút nginx và php-fpm của bạn. Một điều mà điều này có thể cho phép bạn làm chỉ đơn giản là chỉ định một phạm vi (và có thể tạo một docker network) cho các máy chủ php-fpm của bạn (ví dụ: 172,18.0.0 / 24) và có cấu hình HAproxy để thử và sử dụng bất kỳ IP nào trong phạm vi đó làm phụ trợ . Vì HAproxy có kiểm tra sức khỏe, nó có thể nhanh chóng xác định địa chỉ nào đang tồn tại và sử dụng chúng.

Xem /programming/1358198/nginx-removing-upstream-servers-from-pool để biết cuộc thảo luận về cách nginx vs haproxy đối phó với thượng nguồn.

Trừ khi bạn đang sử dụng một mạng docker chuyên dụng cho việc này, bạn có thể cần thực hiện một số quản lý IP thủ công cho các nút php-fpm của mình.


0

Mặc dù bài đăng này là từ năm 2015 và tôi cảm thấy mình đang bị hoại tử (cộng đồng xin lỗi), tôi cảm thấy như nó có giá trị để thêm vào thời điểm này:

Ngày nay (và kể từ khi Kubernetes được đề cập) khi bạn làm việc với Docker, bạn có thể sử dụng Kubernetes hoặc Docker Swarm rất dễ dàng để giải quyết vấn đề này. Cả hai dàn nhạc sẽ nhận các nút docker của bạn (một nút = một máy chủ có Docker trên đó) và bạn có thể triển khai các dịch vụ cho họ và họ sẽ quản lý các thách thức cổng cho bạn bằng cách sử dụng mạng lớp phủ.

Khi tôi thành thạo hơn về Docker Swarm, đây là cách bạn sẽ làm để tiếp cận vấn đề này (giả sử bạn có một nút Docker duy nhất):

Khởi tạo bầy đàn:

docker swarm init

cd vào gốc dự án của bạn

cd some/project/root

tạo một ngăn xếp swarm từ docker-compose.yml của bạn (thay vì sử dụng docker-compose):

docker stack deploy -c docker-compose.yml myApp

Điều này sẽ tạo ra một ngăn xếp dịch vụ docker swarm gọi là "myApp" và sẽ quản lý các cổng cho bạn. Điều này có nghĩa là: Bạn chỉ phải thêm một định nghĩa "port: 9000: 9000" vào dịch vụ php-fpm của mình trong tệp soạn thảo docker và sau đó bạn có thể mở rộng dịch vụ php-fpm, trong 3 trường hợp, trong khi swarm sẽ tự động cân bằng tải một cách kỳ diệu các yêu cầu giữa ba trường hợp mà không cần thêm bất kỳ công việc nào.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.