Thứ ba, 16/09/2014 | 00:00 GMT+7

Cách sử dụng Confd và Etcd để cấu hình lại động các dịch vụ trong CoreOS

CoreOS cho phép bạn dễ dàng chạy các dịch vụ trong containers Docker trên một cụm máy. Thủ tục để thực hiện thường liên quan đến việc bắt đầu một hoặc nhiều trường hợp của một dịch vụ và sau đó đăng ký từng trường hợp với etcd , repository key-value phân tán của CoreOS.

Bằng cách tận dụng mô hình này, các dịch vụ liên quan có thể thu được thông tin có giá trị về trạng thái của cơ sở hạ tầng và sử dụng kiến thức này để thông báo hành vi của chính họ. Điều này giúp các dịch vụ có thể tự động cấu hình khi nào các giá trị etcd quan trọng thay đổi.

Trong hướng dẫn này, ta sẽ thảo luận về một công cụ được gọi là confd , được chế tạo đặc biệt để theo dõi các cửa hàng key-value được phân phối để biết các thay đổi. Nó được chạy từ bên trong containers Docker và được sử dụng để kích hoạt các sửa đổi cấu hình và reload dịch vụ.

Yêu cầu và Mục tiêu

Để làm việc thông qua hướng dẫn này, bạn nên có hiểu biết cơ bản về CoreOS và các bộ phận thành phần của nó. Trong các hướng dẫn trước, ta đã cài đặt một cụm CoreOS và làm quen với một số công cụ được sử dụng để quản lý các cụm của bạn.

Dưới đây là các hướng dẫn mà bạn nên đọc trước khi bắt đầu vào bài viết này. Ta sẽ sửa đổi hoạt động của một số dịch vụ được mô tả trong các hướng dẫn này, vì vậy, mặc dù điều quan trọng là phải hiểu tài liệu, bạn nên bắt đầu mới khi sử dụng hướng dẫn này:

Ngoài ra, để quen thuộc hơn với một số công cụ quản lý mà ta sẽ sử dụng, bạn muốn xem qua các hướng dẫn sau:

Hướng dẫn "Cách tạo Dịch vụ Linh hoạt" đặc biệt quan trọng đối với hướng dẫn này, vì các dịch vụ chính + phụ được tạo mẫu sẽ đóng role là cơ sở cho dịch vụ front-end mà ta sẽ cài đặt trong hướng dẫn này. Như ta đã trình bày trước đó, mặc dù các hướng dẫn ở trên thảo luận về việc tạo các dịch vụ Apache và sidekick, nhưng có một số thay đổi về cấu hình cho hướng dẫn này để bắt đầu từ đầu dễ dàng hơn. Ta sẽ tạo các version sửa đổi của các dịch vụ này trong hướng dẫn này.

Trong hướng dẫn này, ta sẽ tập trung vào việc tạo một containers ứng dụng mới với Nginx. Điều này sẽ đóng role như một Reverse Proxy cho các version Apache khác nhau mà ta có thể tạo ra từ các file mẫu của bạn . Vùng chứa Nginx sẽ được cấu hình với confd để xem đăng ký dịch vụ mà các dịch vụ sidekick của ta chịu trách nhiệm.

Ta sẽ bắt đầu với cùng một cụm ba máy mà ta đã sử dụng trong loạt bài này.

  • coreos-1
  • coreos-2
  • coreos-3

Khi bạn đã đọc xong các hướng dẫn trước đó và có sẵn ba cụm máy, hãy tiếp tục.

Cấu hình Dịch vụ Apache backend

Ta sẽ bắt đầu bằng cách cài đặt các dịch vụ Apache backend của ta . Điều này chủ yếu sẽ phản ánh phần cuối cùng của hướng dẫn trước, nhưng ta sẽ chạy qua toàn bộ quy trình ở đây do một số khác biệt nhỏ.

Đăng nhập vào một trong các máy CoreOS của bạn để bắt đầu:

ssh -A core@ip_address 

Cài đặt containers Apache

Ta sẽ bắt đầu bằng cách tạo containers Apache cơ bản. Điều này thực sự giống với hướng dẫn cuối cùng, vì vậy bạn không phải thực hiện lại điều này nếu bạn đã có sẵn hình ảnh đó trong account Docker Hub của bạn . Ta sẽ đặt containers này dựa trên containers images Ubuntu 14.04.

Ta có thể kéo hình ảnh cơ sở xuống và bắt đầu một version containers bằng lệnh :

docker run -i -t ubuntu:14.04 /bin/bash 

Bạn sẽ được đưa vào một phiên bash khi containers bắt đầu. Từ đây, ta sẽ cập nhật index gói apt local và cài đặt apache2 :

apt-get update apt-get install apache2 -y 

Ta cũng sẽ đặt trang mặc định:

echo "<h1>Running from Docker on CoreOS</h1>" > /var/www/html/index.html 

Ta có thể thoát khỏi containers ngay bây giờ vì nó ở trạng thái ta cần:

exit 

Đăng nhập hoặc tạo account của bạn trên Docker Hub bằng lệnh :

docker login 

Bạn sẽ phải cung cấp tên user , password và địa chỉ email cho account Docker Hub của bạn .

Tiếp theo, lấy ID containers của version bạn vừa để lại:

docker ps -l 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES 1db0c9a40c0d        ubuntu:14.04        "/bin/bash"         2 minutes ago       Exited (0) 4 seconds ago                       jolly_pare 

Trường được đánh dấu ở trên là ID containers . Sao chép kết quả mà bạn thấy trên máy tính của riêng mình.

Bây giờ, hãy commit sử dụng ID containers đó, tên user Docker Hub của bạn và tên cho hình ảnh. Ta sẽ sử dụng “apache” ở đây:

docker commit 1db0c9a40c0d user_name/apache 

Đẩy hình ảnh mới của bạn lên Docker Hub:

docker push user_name/apache 

Bây giờ có thể sử dụng hình ảnh này trong các file dịch vụ của bạn.

Tạo file đơn vị mẫu dịch vụ Apache

Đến đây bạn đã có sẵn containers , bạn có thể tạo file đơn vị mẫu để fleetsystemd có thể quản lý dịch vụ một cách chính xác.

Trước khi bắt đầu, hãy cài đặt cấu trúc folder để ta có thể tổ chức:

cd ~ mkdir static templates instances 

Bây giờ, ta có thể tạo file mẫu của bạn trong folder templates :

vim templates/apache@.service 

Dán thông tin sau vào file . Bạn có thể biết chi tiết về từng tùy chọn mà ta đang sử dụng theo hướng dẫn trước đó về cách tạo file đơn vị đội linh hoạt :

[Unit] Description=Apache web server service on port %i  # Requirements Requires=etcd.service Requires=docker.service Requires=apache-discovery@%i.service  # Dependency ordering After=etcd.service After=docker.service Before=apache-discovery@%i.service  [Service] # Let processes take awhile to start up (for first run Docker containers) TimeoutStartSec=0  # Change killmode from "control-group" to "none" to let Docker remove # work correctly. KillMode=none  # Get CoreOS environmental variables EnvironmentFile=/etc/environment  # Pre-start and Start ## Directives with "=-" are allowed to fail without consequence ExecStartPre=-/usr/bin/docker kill apache.%i ExecStartPre=-/usr/bin/docker rm apache.%i ExecStartPre=/usr/bin/docker pull user_name/apache ExecStart=/usr/bin/docker run --name apache.%i -p ${COREOS_PRIVATE_IPV4}:%i:80 \ user_name/apache /usr/sbin/apache2ctl -D FOREGROUND  # Stop ExecStop=/usr/bin/docker stop apache.%i  [X-Fleet] # Don't schedule on the same machine as other Apache instances Conflicts=apache@*.service 

Một sửa đổi mà ta đã thực hiện ở đây là sử dụng giao diện riêng tư thay vì giao diện công khai. Vì tất cả các version Apache của ta sẽ được chuyển lưu lượng truy cập thông qua Reverse Proxy Nginx thay vì xử lý các kết nối từ web mở, đây là một ý tưởng hay. Lưu ý , nếu bạn sử dụng giao diện riêng tư trên DigitalOcean, server mà bạn tạo ra phải có cờ “mạng riêng tư” được chọn khi tạo.

Ngoài ra, hãy nhớ thay đổi user_name để tham chiếu tên user Docker Hub của bạn để kéo file Docker xuống một cách chính xác.

Tạo file đơn vị mẫu Sidekick

Bây giờ, ta sẽ làm tương tự cho dịch vụ sidekick. Cái này ta sẽ sửa đổi một chút để dự đoán thông tin ta cần sau này.

Mở file mẫu trong editor :

vim templates/apache-discovery@.service 

Ta sẽ sử dụng thông tin sau trong file này:

[Unit] Description=Apache web server on port %i etcd registration  # Requirements Requires=etcd.service Requires=apache@%i.service  # Dependency ordering and binding After=etcd.service After=apache@%i.service BindsTo=apache@%i.service  [Service]  # Get CoreOS environmental variables EnvironmentFile=/etc/environment  # Start ## Test whether service is accessible and then register useful information ExecStart=/bin/bash -c '\   while true; do \     curl -f ${COREOS_PRIVATE_IPV4}:%i; \     if [ $? -eq 0 ]; then \       etcdctl set /services/apache/${COREOS_PRIVATE_IPV4} \'${COREOS_PRIVATE_IPV4}:%i\' --ttl 30; \     else \       etcdctl rm /services/apache/${COREOS_PRIVATE_IPV4}; \     fi; \     sleep 20; \   done'  # Stop ExecStop=/usr/bin/etcdctl rm /services/apache/${COREOS_PRIVATE_IPV4}  [X-Fleet] # Schedule on the same machine as the associated Apache service MachineOf=apache@%i.service 

Cấu hình trên khác với một vài cách so với cấu hình trong hướng dẫn trước. Ta đã điều chỉnh giá trị được đặt bằng lệnh etcdctl set . Thay vì truyền một đối tượng JSON, ta đang cài đặt một tổ hợp địa chỉ IP + cổng đơn giản. Bằng cách này, ta có thể đọc trực tiếp giá trị này để tìm thông tin kết nối cần thiết để truy cập dịch vụ này.

Ta cũng đã điều chỉnh thông tin để chỉ định giao diện riêng tư như ta đã làm trong file khác của bạn . Để nó ở chế độ công khai nếu bạn không có tùy chọn này cho bạn.

Khởi tạo Dịch vụ của bạn

Bây giờ, hãy tạo hai version của các dịch vụ này.

Đầu tiên, hãy tạo các softlink . Di chuyển đến folder ~/instances bạn đã tạo và liên kết để xác định các cổng mà chúng sẽ chạy trên đó. Ta muốn chạy một dịch vụ trên cổng 7777 và một dịch vụ khác tại cổng 8888:

cd ~/instances ln -s ../templates/apache@.service apache@7777.service ln -s ../templates/apache@.service apache@8888.service ln -s ../templates/apache-discovery@.service apache-discovery@7777.service ln -s ../templates/apache-discovery@.service apache-discovery@8888.service 

Bây giờ, ta có thể bắt đầu các dịch vụ này bằng cách chuyển folder ~/instances đến fleet :

fleetctl start ~/instances/* 

Sau khi các version của bạn khởi động (quá trình này có thể mất vài phút), bạn có thể xem các mục nhập etcd mà các sidekicks của bạn đã thực hiện:

etcdctl ls --recursive / 
/coreos.com /coreos.com/updateengine /coreos.com/updateengine/rebootlock /coreos.com/updateengine/rebootlock/semaphore /services /services/apache /services/apache/10.132.249.206 /services/apache/10.132.249.212 

Nếu bạn yêu cầu giá trị của một trong những mục này, bạn có thể thấy rằng bạn nhận được địa chỉ IP và số cổng:

etcdctl get /services/apache/10.132.249.206 
10.132.249.206:8888 

Bạn có thể sử dụng curl để truy xuất trang và đảm bảo nó hoạt động bình thường. Điều này sẽ chỉ hoạt động từ bên trong máy của bạn nếu bạn đã cấu hình dịch vụ để sử dụng mạng riêng:

curl 10.132.249.206:8888 
<h1>Running from Docker on CoreOS</h1> 

Bây giờ ta đã cài đặt cơ sở hạ tầng backend của bạn . Bước tiếp theo của ta là làm quen với confd để ta có thể xem vị trí /services/apache trong etcd để biết các thay đổi và cấu hình lại Nginx mỗi lần.

Tạo containers Nginx

Ta sẽ khởi động containers Nginx từ cùng cơ sở Ubuntu 14.04 mà ta đã sử dụng cho các dịch vụ Apache.

Cài đặt phần mềm

Bắt đầu một containers mới bằng lệnh :

docker run -i -t ubuntu:14.04 /bin/bash 

Cập nhật cache ẩn gói apt local của bạn và cài đặt Nginx. Ta cũng cần cài đặt curl vì hình ảnh cơ sở không bao gồm điều này và ta cần nó để confd gói confd ổn định từ GitHub trong giây lát:

apt-get update apt-get install nginx curl -y 

Bây giờ, ta có thể truy cập trang phát hành cho confd trên GitHub trong trình duyệt của bạn . Ta cần tìm liên kết đến bản phát hành ổn định mới nhất. Tại thời điểm viết bài này, đó là v0.5.0 , nhưng điều này có thể đã thay đổi. Nhấp chuột phải vào liên kết cho version Linux của công cụ và chọn “sao chép địa chỉ liên kết” hoặc bất kỳ tùy chọn tương tự nào khả dụng.

Bây giờ, trở lại containers Docker của bạn, sử dụng URL đã sao chép để download ứng dụng. Ta sẽ đưa nó vào folder /usr/local/bin . Ta cần chọn confd làm file kết quả :

cd /usr/local/bin curl -L https://github.com/kelseyhightower/confd/releases/download/v0.5.0/confd-0.5.0<^>-linux-amd64 -o confd 

Bây giờ, hãy làm cho file thực thi được để ta có thể sử dụng nó trong containers của bạn :

chmod +x confd 

Ta cũng nên tận dụng cơ hội này để tạo cấu trúc cấu hình mà confd mong đợi. Điều này sẽ nằm trong folder /etc :

mkdir -p /etc/confd/{conf.d,templates} 

Tạo một file cấu hình cấu hình để đọc giá trị vv

Bây giờ ta đã cài đặt các ứng dụng của bạn , ta nên bắt đầu cấu hình confd . Ta sẽ bắt đầu bằng cách tạo file cấu hình hoặc file tài nguyên mẫu.

Các file cấu hình trong confd được sử dụng để cài đặt dịch vụ để kiểm tra các giá trị etcd nhất định và bắt đầu hành động khi phát hiện thay đổi. Chúng sử dụng định dạng file TOML , dễ sử dụng và khá trực quan.

Bắt đầu bằng cách tạo một file trong folder cấu hình của ta có tên là nginx.toml :

vi /etc/confd/conf.d/nginx.toml 

Ta sẽ xây dựng file cấu hình của ta trong đây. Thêm thông tin sau:

[template]  # The name of the template that will be used to render the application's configuration file # Confd will look in `/etc/conf.d/templates` for these files by default src = "nginx.tmpl"  # The location to place the rendered configuration file dest = "/etc/nginx/sites-enabled/app.conf"  # The etcd keys or directory to watch.  This is where the information to fill in # the template will come from. keys = [ "/services/apache" ]  # File ownership and mode information owner = "root" mode = "0644"  # These are the commands that will be used to check whether the rendered config is # valid and to reload the actual service once the new config is in place check_cmd = "/usr/sbin/nginx -t" reload_cmd = "/usr/sbin/service nginx reload" 

Tệp trên có comment giải thích một số ý tưởng cơ bản, nhưng ta có thể xem qua các tùy chọn bạn có bên dưới:

Chỉ thị Cần thiết? Kiểu Sự miêu tả
src Đúng Chuỗi Tên của mẫu sẽ được sử dụng để hiển thị thông tin. Nếu điều này nằm bên ngoài /etc/confd/templates , thì toàn bộ đường dẫn sẽ được sử dụng.
đích Đúng Chuỗi Vị trí file nơi file cấu hình được kết xuất sẽ được đặt.
key Đúng Mảng chuỗi Các khóa etcd mà mẫu yêu cầu phải được hiển thị chính xác. Đây có thể là một folder nếu mẫu được cài đặt để xử lý các khóa con.
chủ nhân Không Chuỗi Tên user sẽ được cấp quyền sở hữu file cấu hình được hiển thị.
group Không Chuỗi Group sẽ được cấp quyền sở hữu group đối với file cấu hình được hiển thị.
chế độ Không Chuỗi Chế độ quyền bát phân phải được đặt cho file kết xuất.
check_cmd Không Chuỗi Lệnh sẽ được sử dụng để kiểm tra cú pháp của file cấu hình được kết xuất.
reload_cmd Không Chuỗi Lệnh sẽ được sử dụng để reload cấu hình của ứng dụng.
tiếp đầu ngữ Không Chuỗi Một phần của cấu etcd phân cấp etcd đứng trước các khóa trong chỉ thị keys . Điều này được dùng để làm cho file .toml linh hoạt hơn.

Tệp mà ta đã tạo cho ta biết một số điều quan trọng về cách confd của ta sẽ hoạt động. Vùng chứa Nginx của ta sẽ sử dụng mẫu được lưu trữ tại /etc/confd/templates/nginx.conf.tmpl để hiển thị file cấu hình sẽ được đặt tại /etc/nginx/sites-enabled/app.conf . Tệp sẽ được cấp tập hợp quyền là 0644 và quyền sở hữu sẽ được trao cho user root.

Ứng dụng confd sẽ tìm kiếm các thay đổi tại nút /services/apache . Khi một thay đổi được nhìn thấy, confd sẽ truy vấn thông tin mới trong nút đó. Sau đó, nó sẽ hiển thị một cấu hình mới cho Nginx. Nó sẽ kiểm tra file cấu hình để tìm lỗi cú pháp và reload dịch vụ Nginx sau khi file ở vị trí.

Bây giờ ta đã tạo file tài nguyên mẫu của ta . Ta nên làm việc trên file mẫu thực tế sẽ được sử dụng để hiển thị file cấu hình Nginx của ta .

Tạo file mẫu cấu hình

Đối với file mẫu của ta , ta sẽ sử dụng một ví dụ từtài liệu GitHub của dự án confd để bắt đầu.

Tạo file mà ta đã tham chiếu trong file cấu hình của ta ở trên. Đặt file này vào folder templates của ta :

vi /etc/confd/templates/nginx.tmpl 

Trong file này, về cơ bản ta chỉ tạo lại file cấu hình Reverse Proxy Nginx tiêu chuẩn. Tuy nhiên, ta sẽ sử dụng một số cú pháp khuôn mẫu Go để thay thế một số thông tin mà confd đang lấy từ etcd .

Đầu tiên, ta cấu hình khối với các server “ngược dòng”. Phần này được sử dụng để xác định group server mà Nginx có thể gửi yêu cầu đến. Định dạng thường như thế này:

upstream pool_name {     server server_1_IP:port_num;     server server_2_IP:port_num;     server server_3_IP:port_num; } 

Điều này cho phép ta chuyển các yêu cầu đến pool_name và Nginx sẽ chọn một trong các server được xác định để gửi yêu cầu đến.

Ý tưởng đằng sau file mẫu của ta là phân tích cú pháp etcd cho địa chỉ IP và số cổng của web server Apache của ta . Vì vậy, thay vì xác định tĩnh các server ngược dòng của ta , ta nên tự động điền thông tin này vào khi file được hiển thị. Ta có thể làm điều này bằng cách sử dụng các mẫu Go cho nội dung động.

Để làm điều này, thay vào đó, ta sẽ sử dụng khối này làm khối của ta :

upstream apache_pool { {{ range getvs "/services/apache/*" }}     server {{ . }}; {{ end }} } 

Hãy giải thích một chút những gì đang xảy ra. Ta đã mở một khối để xác định một group server ngược dòng được gọi là apache_pool . Bên trong, ta chỉ định rằng ta đang bắt đầu một số mã ngôn ngữ Go bằng cách sử dụng dấu ngoặc kép.

Trong các dấu ngoặc này, ta chỉ định điểm cuối etcd nơi chứa các giá trị mà ta quan tâm. Ta đang sử dụng một range để làm cho danh sách có thể lặp lại.

Ta sử dụng điều này để chuyển tất cả các mục nhập được truy xuất từ bên dưới vị trí /services/apache trong etcd vào khối range . Sau đó, ta có thể lấy giá trị của khóa trong lần lặp hiện tại bằng cách sử dụng một dấu chấm trong “{{” và “}}” cho biết một giá trị được chèn vào. Ta sử dụng điều này trong vòng lặp phạm vi để điền group server . Cuối cùng, ta kết thúc vòng lặp với lệnh {{ end }} .

Lưu ý : Hãy nhớ thêm dấu chấm phẩy sau lệnh server trong vòng lặp. Quên điều này sẽ dẫn đến cấu hình không hoạt động.

Sau khi cài đặt group server , ta chỉ có thể sử dụng thẻ proxy để chuyển hướng tất cả các kết nối vào group server đó. Đây sẽ chỉ là một khối server tiêu chuẩn như một Reverse Proxy . Một điều cần lưu ý là access_log , sử dụng định dạng tùy chỉnh mà ta sẽ tạo trong giây lát:

upstream apache_pool { {{ range getvs "/services/apache/*" }}     server {{ . }}; {{ end }} }  server {     listen 80 default_server;     listen [::]:80 default_server ipv6only=on;      access_log /var/log/nginx/access.log upstreamlog;      location / {         proxy_pass http://apache_pool;         proxy_redirect off;         proxy_set_header Host $host;         proxy_set_header X-Real-IP $remote_addr;         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;     } } 

Điều này sẽ phản hồi tất cả các kết nối trên cổng 80 và chuyển chúng đến group server tại apache_pool được tạo bằng cách xem các mục nhập etcd .

Trong khi xử lý khía cạnh này của dịch vụ, ta nên xóa file cấu hình Nginx mặc định để không gặp phải xung đột sau này. Ta sẽ chỉ xóa softlink cho phép cấu hình mặc định:

rm /etc/nginx/sites-enabled/default 

Bây giờ cũng là thời điểm tốt để cấu hình định dạng log mà ta đã tham chiếu trong file mẫu của bạn . Điều này phải đi trong khối http của cấu hình, có sẵn trong file cấu hình chính. Mở nó ngay bây giờ:

vi /etc/nginx/nginx.conf 

Ta sẽ thêm một chỉ thị log_format để xác định thông tin ta muốn ghi lại. Nó sẽ ghi lại client đang truy cập, cũng như server backend mà yêu cầu được chuyển đến. Ta sẽ ghi lại một số dữ liệu về khoảng thời gian mà các thủ tục này mất:

. . . http {     ##     # Basic Settings     ##     log_format upstreamlog '[$time_local] $remote_addr passed to: $upstream_addr: $request Upstream Response Time: $upstream_response_time Request time: $request_time';      sendfile on;     . . . 

Lưu file khi bạn hoàn tất.

Tạo tập lệnh để chạy cấu hình

Ta cần tạo một file script sẽ gọi confd với file tài nguyên mẫu và file mẫu của ta vào những thời điểm thích hợp.

Tập lệnh phải thực hiện hai điều để dịch vụ của ta hoạt động chính xác:

  • Nó phải chạy khi containers chạy để cài đặt cài đặt Nginx ban đầu dựa trên trạng thái hiện tại của cơ sở hạ tầng backend .
  • Nó phải tiếp tục theo dõi các thay đổi đối với đăng ký etcd cho các server Apache để có thể cấu hình lại Nginx dựa trên các server backend có sẵn.

Ta sẽ lấy kịch bản của bạn từ trang GitHub của Marcel de Graaf . Đây là một tập lệnh đơn giản, đẹp mắt và thực hiện đúng những gì ta cần. Ta sẽ chỉ thực hiện một số chỉnh sửa nhỏ cho kịch bản của bạn .

Hãy đặt tập lệnh này cùng với file thực thi confd của ta . Ta sẽ gọi đây là confd-watch :

vi /usr/local/bin/confd-watch 

Ta sẽ bắt đầu với tiêu đề bash thông thường để xác định trình thông dịch mà ta cần. Sau đó, ta sẽ đặt một số tùy chọn bash để tập lệnh không thành công ngay lập tức nếu có bất kỳ điều gì sai. Nó sẽ trả về giá trị của lệnh cuối cùng bị lỗi hoặc chạy.

#!/bin/bash  set -eo pipefail 

Tiếp theo, ta muốn cài đặt một số biến. Bằng cách sử dụng thay thế tham số bash , ta sẽ đặt các giá trị mặc định, nhưng xây dựng theo một số tính linh hoạt để cho phép ta overrides các giá trị được mã hóa cứng khi gọi tập lệnh. Về cơ bản, điều này sẽ chỉ cài đặt từng thành phần của địa chỉ kết nối một cách độc lập và sau đó group chúng lại với nhau để có được địa chỉ đầy đủ cần thiết.

Thay thế tham số được tạo với cú pháp sau: ${ var_name :- default_value } . Điều này có thuộc tính sử dụng giá trị của var_name nếu nó được cung cấp và không phải null, nếu không thì mặc định là default_value .

Ta đang mặc định các giá trị mà etcd mong đợi theo mặc định. Điều này sẽ cho phép tập lệnh của ta hoạt động tốt mà không cần thông tin bổ sung, nhưng ta có thể tùy chỉnh khi cần thiết khi gọi tập lệnh:

#!/bin/bash  set -eo pipefail  export ETCD_PORT=${ETCD_PORT:-4001} export HOST_IP=${HOST_IP:-172.17.42.1} export ETCD=$HOST_IP:$ETCD_PORT 

Bây giờ ta sẽ sử dụng confd để hiển thị version ban đầu của file cấu hình Nginx bằng cách đọc các giá trị từ etcd có sẵn khi tập lệnh này được gọi. Ta sẽ sử dụng một vòng lặp until liên tục cố gắng xây dựng cấu hình ban đầu.

Cấu trúc lặp có thể cần thiết trong trường hợp etcd không có sẵn ngay lập tức hoặc trong trường hợp containers Nginx được đưa trực tuyến trước các server backend . Điều này cho phép nó thăm dò etcd nhiều lần cho đến khi cuối cùng nó có thể tạo ra một cấu hình ban đầu hợp lệ.

Lệnh confd thực tế mà ta đang gọi thực hiện một lần và sau đó thoát. Vì vậy, ta có thể đợi 5 giây cho đến lần chạy tiếp theo để cho các server backend của ta có cơ hội đăng ký. Ta kết nối với biến ETCD đầy đủ mà ta đã tạo bằng cách sử dụng các tham số mặc định hoặc được chuyển vào và ta sử dụng file tài nguyên mẫu để xác định hành vi của những gì ta muốn làm:

#!/bin/bash  set -eo pipefail  export ETCD_PORT=${ETCD_PORT:-4001} export HOST_IP=${HOST_IP:-172.17.42.1} export ETCD=$HOST_IP:$ETCD_PORT  echo "[nginx] booting container. ETCD: $ETCD"  # Try to make initial configuration every 5 seconds until successful until confd -onetime -node $ETCD -config-file /etc/confd/conf.d/nginx.toml; do     echo "[nginx] waiting for confd to create initial nginx configuration"     sleep 5 done 

Sau khi cấu hình ban đầu đã được cài đặt , nhiệm vụ tiếp theo của tập lệnh của ta là đặt ra một cơ chế để thăm dò liên tục. Ta muốn đảm bảo mọi thay đổi trong tương lai đều được phát hiện để Nginx sẽ được cập nhật.

Để làm điều này, ta có thể gọi confd . Lần này, ta muốn đặt khoảng thời gian bỏ phiếu liên tục và đặt quy trình trong nền để nó chạy vô thời hạn. Ta sẽ chuyển cùng một thông tin kết nối etcd và cùng một file tài nguyên mẫu vì mục tiêu của ta vẫn giống nhau.

Sau khi đưa các confd quá trình vào nền, ta có thể yên tâm bắt đầu Nginx sử dụng file cấu hình đã được thực hiện. Vì tập lệnh này sẽ được gọi là lệnh Docker “run” của ta , ta cần giữ cho nó chạy ở nền trước để containers không thoát ra tại thời điểm này. Ta có thể làm điều này bằng cách chỉ cần gắn thẻ các log , cho phép ta truy cập vào tất cả thông tin mà ta đã ghi log :

#!/bin/bash  set -eo pipefail  export ETCD_PORT=${ETCD_PORT:-4001} export HOST_IP=${HOST_IP:-172.17.42.1} export ETCD=$HOST_IP:$ETCD_PORT  echo "[nginx] booting container. ETCD: $ETCD."  # Try to make initial configuration every 5 seconds until successful until confd -onetime -node $ETCD -config-file /etc/confd/conf.d/nginx.toml; do     echo "[nginx] waiting for confd to create initial nginx configuration."     sleep 5 done  # Put a continual polling `confd` process into the background to watch # for changes every 10 seconds confd -interval 10 -node $ETCD -config-file /etc/confd/conf.d/nginx.toml & echo "[nginx] confd is now monitoring etcd for changes..."  # Start the Nginx service using the generated config echo "[nginx] starting nginx service..." service nginx start  # Follow the logs to allow the script to continue running tail -f /var/log/nginx/*.log 

Khi bạn hoàn thành việc này, hãy lưu file .

Điều cuối cùng ta cần làm là làm cho tập lệnh có thể thực thi được:

chmod +x /usr/local/bin/confd-watch 

Thoát khỏi containers ngay bây giờ để quay lại hệ thống server :

exit 

Commit và đẩy containers

Bây giờ, ta có thể commit containers và đẩy nó lên Docker Hub để nó có sẵn cho máy của ta để kéo xuống.

Tìm hiểu ID containers :

docker ps -l 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES de4f30617499        ubuntu:14.04        "/bin/bash"         22 hours ago        Exited (0) About a minute ago                       stupefied_albattani 

Chuỗi được đánh dấu là ID containers mà ta cần. Commit containers bằng cách sử dụng ID này cùng với tên user Docker Hub của bạn và tên bạn muốn sử dụng cho hình ảnh này. Ta sẽ sử dụng tên “nginx_lb” trong hướng dẫn này:

docker commit de4f30617499 user_name/nginx_lb 

Đăng nhập vào account Docker Hub của bạn nếu cần:

docker login 

Bây giờ, bạn nên đẩy hình ảnh đã commit của bạn lên để các server khác của bạn có thể kéo nó xuống khi cần thiết:

docker push user_name/nginx_lb 

Xây dựng file đơn vị tĩnh Nginx

Bước tiếp theo là xây dựng một file đơn vị sẽ khởi động containers mà ta vừa tạo. Điều này sẽ cho phép ta sử dụng fleet để kiểm soát quá trình.

Vì đây sẽ không phải là một mẫu, ta sẽ đặt nó vào folder ~/static mà ta đã tạo ở đầu folder này:

vim static/nginx_lb.service 

Ta sẽ bắt đầu với phần [Unit] tiêu chuẩn để mô tả dịch vụ và xác định các yếu tố phụ thuộc và thứ tự:

[Unit] Description=Nginx load balancer for web server backends  # Requirements Requires=etcd.service Requires=docker.service  # Dependency ordering After=etcd.service After=docker.service 

Tiếp theo, ta cần xác định phần [Service] của file . Ta sẽ đặt thời gian chờ thành 0 và điều chỉnh killmode thành không nữa, giống như ta đã làm với các file dịch vụ Apache. Ta sẽ kéo lại file môi trường để ta có thể truy cập vào các địa chỉ IP công cộng và riêng tư của server mà containers này đang chạy.

Sau đó, ta sẽ dọn dẹp môi trường của bạn đảm bảo rằng mọi version trước của containers này đều bị dừng và bị xóa. Ta kéo containers vừa tạo xuống đảm bảo rằng ta luôn có version mới nhất.

Cuối cùng, ta sẽ bắt đầu container. Điều này liên quan đến việc khởi động containers , đặt cho nó tên mà ta đã tham chiếu trong các lệnh remove and kill và chuyển nó địa chỉ IP công cộng của server mà nó đang chạy tới cổng ánh xạ 80. Ta gọi tập confd-watch mà ta đã viết là chạy chỉ huy.

[Unit] Description=Nginx load balancer for web server backends  # Requirements Requires=etcd.service Requires=docker.service  # Dependency ordering After=etcd.service After=docker.service  [Service] # Let the process take awhile to start up (for first run Docker containers) TimeoutStartSec=0  # Change killmode from "control-group" to "none" to let Docker remove # work correctly. KillMode=none  # Get CoreOS environmental variables EnvironmentFile=/etc/environment  # Pre-start and Start ## Directives with "=-" are allowed to fail without consequence ExecStartPre=-/usr/bin/docker kill nginx_lb ExecStartPre=-/usr/bin/docker rm nginx_lb ExecStartPre=/usr/bin/docker pull user_name/nginx_lb ExecStart=/usr/bin/docker run --name nginx_lb -p ${COREOS_PUBLIC_IPV4}:80:80 \ user_name/nginx_lb /usr/local/bin/confd-watch 

Bây giờ, tất cả những gì ta cần sắp xếp là lệnh dừng và các hướng dẫn lên lịch trình của fleet . Ta muốn containers này chỉ được khởi tạo trên các server không chạy các version cân bằng tải khác hoặc server Apache backend . Điều này sẽ cho phép dịch vụ của ta phân bổ tải một cách hiệu quả:

[Unit] Description=Nginx load balancer for web server backends  # Requirements Requires=etcd.service Requires=docker.service  # Dependency ordering After=etcd.service After=docker.service  [Service] # Let the process take awhile to start up (for first run Docker containers) TimeoutStartSec=0  # Change killmode from "control-group" to "none" to let Docker remove # work correctly. KillMode=none  # Get CoreOS environmental variables EnvironmentFile=/etc/environment  # Pre-start and Start ## Directives with "=-" are allowed to fail without consequence ExecStartPre=-/usr/bin/docker kill nginx_lb ExecStartPre=-/usr/bin/docker rm nginx_lb ExecStartPre=/usr/bin/docker pull user_name/nginx_lb ExecStart=/usr/bin/docker run --name nginx_lb -p ${COREOS_PUBLIC_IPV4}:80:80 \ user_name/nginx_lb /usr/local/bin/confd-watch  # Stop ExecStop=/usr/bin/docker stop nginx_lb  [X-Fleet] Conflicts=nginx.service Conflicts=apache@*.service 

Lưu file khi bạn hoàn tất.

Chạy Trình cân bằng tải Nginx

Bạn đã có hai version Apache đang chạy trước đó trong hướng dẫn. Bạn có thể kiểm tra bằng lệnh :

fleetctl list-units 
UNIT                MACHINE             ACTIVE  SUB apache-discovery@7777.service   197a1662.../10.132.249.206  active  running apache-discovery@8888.service   04856ec4.../10.132.249.212  active  running apache@7777.service     197a1662.../10.132.249.206  active  running apache@8888.service     04856ec4.../10.132.249.212  active  running 

Bạn cũng có thể kiểm tra lại xem họ có đăng ký chính xác với etcd bằng lệnh :

etcdctl ls --recursive /services/apache 
/services/apache/10.132.249.206 /services/apache/10.132.249.212 

Bây giờ ta có thể cố gắng khởi động dịch vụ Nginx của bạn :

fleetctl start ~/static/nginx_lb.service 
Unit nginx_lb.service launched on 96ec72cf.../10.132.248.177 

Có thể mất một phút hoặc lâu hơn để dịch vụ bắt đầu, tùy thuộc vào thời gian kéo hình ảnh xuống. Sau khi nó được khởi động, nếu bạn kiểm tra log bằng lệnh fleetctl journal , bạn có thể xem một số thông tin log từ confd . Nó trông giống như sau :

fleetctl journal nginx_lb.service 
-- Logs begin at Mon 2014-09-15 14:54:05 UTC, end at Tue 2014-09-16 17:13:58 UTC. -- Sep 16 17:13:48 lala1 docker[15379]: 2014-09-16T17:13:48Z d7974a70e976 confd[14]: INFO Target config /etc/nginx/sites-enabled/app.conf out of sync Sep 16 17:13:48 lala1 docker[15379]: 2014-09-16T17:13:48Z d7974a70e976 confd[14]: INFO Target config /etc/nginx/sites-enabled/app.conf has been updated Sep 16 17:13:48 lala1 docker[15379]: [nginx] confd is monitoring etcd for changes... Sep 16 17:13:48 lala1 docker[15379]: [nginx] starting nginx service... Sep 16 17:13:48 lala1 docker[15379]: 2014-09-16T17:13:48Z d7974a70e976 confd[33]: INFO Target config /etc/nginx/sites-enabled/app.conf in sync Sep 16 17:13:48 lala1 docker[15379]: ==> /var/log/nginx/access.log <== Sep 16 17:13:48 lala1 docker[15379]: ==> /var/log/nginx/error.log <== Sep 16 17:13:58 lala1 docker[15379]: 2014-09-16T17:13:58Z d7974a70e976 confd[33]: INFO /etc/nginx/sites-enabled/app.conf has md5sum a8517bfe0348e9215aa694f0b4b36c9b should be 33f42e3b7cc418f504237bea36c8a03e Sep 16 17:13:58 lala1 docker[15379]: 2014-09-16T17:13:58Z d7974a70e976 confd[33]: INFO Target config /etc/nginx/sites-enabled/app.conf out of sync Sep 16 17:13:58 lala1 docker[15379]: 2014-09-16T17:13:58Z d7974a70e976 confd[33]: INFO Target config /etc/nginx/sites-enabled/app.conf has been updated 

Như bạn thấy , confd đã tìm đến etcd cho cấu hình ban đầu của nó. Sau đó nó bắt đầu nginx . Sau đó, ta có thể thấy các dòng trong đó các mục nhập etcd đã được đánh giá lại và một file cấu hình mới được tạo. Nếu file mới được tạo không trùng với md5sum của file tại chỗ, file sẽ bị chuyển ra ngoài và dịch vụ được reload .

Điều này cho phép dịch vụ cân bằng tải của ta cuối cùng theo dõi các server backend Apache của ta . Nếu confd dường như liên tục cập nhật, có thể là do các version Apache của bạn đang làm mới TTL của chúng quá thường xuyên. Bạn có thể tăng giá trị sleep và TTL trong mẫu sidekick để tránh điều này.

Để xem trình cân bằng tải đang hoạt động, bạn có thể yêu cầu file /etc/environments từ server đang chạy dịch vụ Nginx. Điều này chứa địa chỉ IP công cộng của server . Nếu bạn muốn cải thiện cấu hình này tốt hơn, hãy cân nhắc chạy dịch vụ sidekick đăng ký thông tin này với etcd , giống như ta đã làm đối với các version Apache:

fleetctl ssh nginx_lb cat /etc/environment 
COREOS_PRIVATE_IPV4=10.132.248.177 COREOS_PUBLIC_IPV4=104.131.16.222 

Bây giờ, nếu ta truy cập địa chỉ IPv4 công khai trong trình duyệt của bạn , ta sẽ thấy trang mà ta đã cấu hình trong các version Apache của bạn :

Trang index  Apache

Bây giờ, nếu bạn xem lại log của bạn , bạn có thể thấy thông tin cho biết server backend nào đã thực sự được thông qua yêu cầu:

fleetctl journal nginx_lb 
. . . Sep 16 18:04:38 lala1 docker[18079]: 2014-09-16T18:04:38Z 51c74658196c confd[28]: INFO Target config /etc/nginx/sites-enabled/app.conf in sync Sep 16 18:04:48 lala1 docker[18079]: 2014-09-16T18:04:48Z 51c74658196c confd[28]: INFO Target config /etc/nginx/sites-enabled/app.conf in sync Sep 16 18:04:48 lala1 docker[18079]: [16/Sep/2014:18:04:48 +0000] 108.29.37.206 passed to: 10.132.249.212:8888: GET / HTTP/1.1 Upstream Response Time: 0.003 Request time: 0.003 

Kết luận

Như bạn thấy, có thể cài đặt các dịch vụ của bạn để kiểm tra etcd để biết chi tiết cấu hình. Các công cụ như confd có thể làm cho quá trình này tương đối đơn giản bằng cách cho phép bỏ phiếu liên tục các mục quan trọng.

Trong ví dụ trong hướng dẫn này, ta đã cấu hình dịch vụ Nginx của bạn để sử dụng etcd để tạo cấu hình ban đầu của nó. Ta cũng cài đặt nó ở chế độ nền để liên tục kiểm tra các thay đổi. Điều này, kết hợp với việc tạo cấu hình động dựa trên các mẫu cho phép ta luôn có hình ảnh cập nhật về các server backend của bạn .


Tags:

Các tin liên quan