Thứ hai, 07/11/2016 | 00:00 GMT+7

Cơ sở hạ tầng SaltStack: Tạo Salt State cho web server Nginx

SaltStack, hay Salt, là một hệ thống quản lý cấu hình và thực thi từ xa mạnh mẽ được dùng để dễ dàng quản lý cơ sở hạ tầng theo cách có cấu trúc, có thể lặp lại. Trong loạt bài này, ta sẽ trình bày một phương pháp quản lý môi trường phát triển, dàn dựng và production của bạn từ việc triển khai Salt. Ta sẽ sử dụng hệ thống trạng thái Salt để viết và áp dụng các hành động có thể lặp lại. Điều này sẽ cho phép ta phá hủy bất kỳ môi trường nào của ta , an toàn khi biết rằng ta có thể dễ dàng đưa chúng trở lại trực tuyến ở trạng thái giống hệt nhau sau này.

Trong hướng dẫn trước của ta , ta đã mở rộng khả năng của server Salt master bằng cách cài đặt nhà cung cấp DigitalOcean cho salt-cloud . Ta đã tạo các file cần thiết để cho phép ta tạo ra các server mới cho mỗi môi trường của ta . Trong bài viết này, ta sẽ bắt đầu đi sâu vào quản lý cấu hình bằng cách tạo các file trạng thái Salt cho Nginx. Nginx sẽ được sử dụng trên các node web server của ta trong cả ba môi trường để xử lý các yêu cầu web.

Tạo file trạng thái Nginx chính

Salt xử lý việc quản lý cấu hình thông qua hệ thống trạng thái của nó. Trong trường hợp đơn giản nhất, chúng được kiểm soát bởi các file nằm trong root server file của Salt (mà ta đã cấu hình là /srv/salt ). Để bắt đầu cấu hình Nginx của ta , ta sẽ tạo một folder ở vị trí này dành riêng cho phần mềm ta đang cấu hình :

  • sudo mkdir /srv/salt/nginx

Các file trạng thái có hậu tố .sls . init.sls trong folder có chức năng như file cấu hình chính cho trạng thái hoặc công thức Salt cụ thể đó. Ta tham chiếu đến tên folder mẹ để thực thi chức năng có trong file init.sls liên kết.

Với ý nghĩ đó, hãy tạo và mở file init.sls trong folder này để bắt đầu:

  • sudo nano /srv/salt/nginx/init.sls

Các trạng thái gói và dịch vụ của Nginx

Ta sẽ bắt đầu bằng cách tạo một trạng thái bằng cách sử dụng mã định danh nginx . Đây sẽ là tên duy nhất cho trạng thái cụ thể này trong hệ thống trạng thái Salt. Vì ta sẽ không bao gồm thuộc tính “name” cho các module trạng thái của ta , nó cũng sẽ đóng role là mục tiêu được cài đặt (đối với hàm pkg.installed ) và dịch vụ đang chạy (đối với hàm service.running ).

Ta muốn Nginx tự động reload trong các điều kiện nhất định: khi gói được cập nhật, khi file cấu hình chính đã được thay đổi hoặc khi file khối server mặc định được sửa đổi. Ta có thể yêu cầu Salt khởi động lại dịch vụ Nginx khi các điều kiện này xảy ra bằng cách sử dụng watch :

/srv/salt/nginx/init.sls
nginx:   pkg:     - installed   service.running:     - watch:       - pkg: nginx       - file: /etc/nginx/nginx.conf       - file: /etc/nginx/sites-available/default 

Các phím pkg: and file: bên dưới watch: phím đại diện cho các module trạng thái được liên kết với các tài nguyên cần xem. Tài nguyên pkg được quan tâm trong phần đầu tiên của cùng định nghĩa này. Tiếp theo, ta sẽ phải tạo các trạng thái để trùng với tài nguyên file .

Trạng thái file cấu hình Nginx

Ta có thể bắt đầu với file /etc/nginx/nginx.conf . Ta muốn đặt file này thành một file được quản lý. Theo thuật ngữ Salt, điều này chỉ nghĩa là ta sẽ xác định nội dung của file trên server chính và tải nó lên từng minion cần nó. Ta sẽ cài đặt các quyền và quyền sở hữu khá điển hình trên file . Nguồn tham chiếu đến một vị trí trong server file Salt (tệp hiện tại của ta cũng nằm trong cấu trúc này). Ta sẽ tạo đường dẫn và file này trong giây lát:

/srv/salt/nginx/init.sls
nginx:   pkg:     - installed   service.running:     - watch:       - pkg: nginx       - file: /etc/nginx/nginx.conf       - file: /etc/nginx/sites-available/default  /etc/nginx/nginx.conf:   file.managed:     - source: salt://nginx/files/etc/nginx/nginx.conf     - user: root     - group: root     - mode: 640 

Ta cũng muốn kiểm soát nội dung của file /etc/nginx/sites-available/default . Điều này xác định khối server kiểm soát cách nội dung của ta sẽ được phân phát. Khối trạng thái khá giống với khối cuối cùng. Sự khác biệt chính là file này sẽ là một mẫu Jinja.

Các mẫu Jinja cho phép Salt tùy chỉnh một số nội dung của file với các chi tiết cụ thể cho từng tay sai nơi nó sẽ được đặt. Điều này nghĩa là ta có thể lấy thông tin từ mỗi server lưu trữ và xây dựng một version file tùy chỉnh, thích hợp cho từng web server của ta . Ta cho biết rằng file này sẽ sử dụng Jinja với tùy chọn template . Ta cũng sẽ sử dụng hậu tố .jinja trên file nguồn để có thể biết ngay rằng file đó là một mẫu:

/srv/salt/nginx/init.sls
. . .  /etc/nginx/nginx.conf:   file.managed:     - source: salt://nginx/files/etc/nginx/nginx.conf     - user: root     - group: root     - mode: 640  /etc/nginx/sites-available/default:   file.managed:     - source: salt://nginx/files/etc/nginx/sites-available/default.jinja     - template: jinja     - user: root     - group: root     - mode: 640 

Ta có file khối server mặc định của ta dự kiến sẽ được đặt trong folder sites-available trên các server minion. Tuy nhiên, ta vẫn cần liên kết file với folder sites-enabled để kích hoạt nó. Ta có thể làm điều đó với hàm file.symlink . Ta chỉ cần cung cấp vị trí file root làm target . Ta cũng cần “yêu cầu” file đó để trạng thái này chỉ được thực thi sau khi trạng thái trước đó đã hoàn thành :

/srv/salt/nginx/init.sls
. . .  /etc/nginx/sites-available/default:   file.managed:     - source: salt://nginx/files/etc/nginx/sites-available/default.jinja     - template: jinja     - user: root     - group: root     - mode: 640  /etc/nginx/sites-enabled/default:   file.symlink:     - target: /etc/nginx/sites-available/default     - require:       - file: /etc/nginx/sites-available/default 

Trạng thái cho Nội dung Trang web Mặc định của Ta

Ta đã viết các trạng thái cài đặt và cấu hình Nginx của ta . Bây giờ, ta chỉ cần tạo một trạng thái cho index.html của ta , đây sẽ là nội dung thực tế cho trang web của ta .

Trạng thái này sử dụng định dạng giống hệt như trạng thái mẫu trước đó của ta . Sự khác biệt duy nhất là số nhận dạng, nguồn và chế độ quyền trên file này:

/srv/salt/nginx/init.sls
. . .  /etc/nginx/sites-enabled/default:   file.symlink:     - target: /etc/nginx/sites-available/default     - require:       - file: /etc/nginx/sites-available/default  /usr/share/nginx/html/index.html:   file.managed:     - source: salt://nginx/files/usr/share/nginx/html/index.html.jinja     - template: jinja     - user: root     - group: root     - mode: 644 

Khi bạn hoàn tất, hãy lưu file này. Ta đã hoàn thành với thông tin trạng thái Nginx thực tế cho thời điểm này.

Cài đặt Nginx và chuyển các file root sang Salt Master

Ta đã tạo file trạng thái Nginx Salt chính của ta . Tuy nhiên, một số trạng thái ta đã tạo file tham chiếu trên server file của Salt master chưa tồn tại.

Vì các file của ta phần lớn giống với các file mặc định được cài đặt bởi gói Nginx của Ubuntu, cách dễ nhất để ta bắt đầu là với các file từ gói đó. Các web server từ một trong các môi trường của ta cung cấp một nơi hoàn hảo để cài đặt Nginx để ta có thể lấy các file cần thiết.

Nếu bạn chưa có một trong các môi trường của bạn , hãy chọn một trong các file bản đồ môi trường của bạn để triển khai. Ta sẽ sử dụng môi trường “sân khấu” trong loạt bài này vì đây là môi trường nhỏ nhất có tất cả các loại server mà ta cần.

  • sudo salt-cloud -P -m /etc/salt/cloud.maps.d/stage-environment.map

Sau khi server của bạn hoạt động, hãy chọn một trong các web server của bạn để cài đặt Nginx vào. Ta sẽ chỉ sử dụng module thực thi pkg tại thời điểm này, vì các trạng thái của ta chưa hoạt động đầy đủ:

  • sudo salt stage-www1 pkg.install nginx

Khi ta cài đặt cấu hình chính của Salt, ta đã bật tùy chọn file_recv . Điều này cho phép ta yêu cầu tay sai đẩy các file nhất định trở lại file chính. Ta có thể sử dụng điều này để lấy các version mặc định của file mà ta sẽ quản lý:

  • sudo salt stage-www1 cp.push /etc/nginx/nginx.conf
  • sudo salt stage-www1 cp.push /etc/nginx/sites-available/default
  • sudo salt stage-www1 cp.push /usr/share/nginx/html/index.html

Các file này bây giờ sẽ có sẵn trên bản chính. Đường dẫn đến các file này được tạo lại trong folder /var/cache/salt/master/minions/ minion_id /files . Trong trường hợp của ta , ID minion sẽ là stage-www1 . Ta có thể sao chép các folder bên dưới vị trí này, đại diện cho các đường dẫn file trên minion, vào folder trạng thái Salt của ta bằng lệnh :

  • sudo cp -r /var/cache/salt/master/minions/stage-www1/files /srv/salt/nginx

Nếu bạn nhìn vào nội dung của folder trạng thái của bạn , bạn sẽ thấy một folder mới được gọi là "tệp". Bên dưới folder này, các folder liên quan trong hệ thống file của minion và ba file ta đã sao chép có sẵn:

  • find /srv/salt/nginx -printf "%P\n"
Output
files files/usr files/usr/share files/usr/share/nginx files/usr/share/nginx/html files/usr/share/nginx/html/index.html files/etc files/etc/nginx files/etc/nginx/sites-available files/etc/nginx/sites-available/default files/etc/nginx/nginx.conf init.sls

Đây là nơi tất cả các file được quản lý của ta sẽ được duy trì. Điều này phù hợp với vị trí "nguồn" mà ta đặt trong file trạng thái Nginx của bạn .

Vì bây giờ ta có tất cả các file ta cần lấy từ minion nơi Nginx đã được cài đặt, ta có thể phá hủy minion và xây dựng lại nó. Điều này sẽ đảm bảo sau này, các file trạng thái của ta có thể được kiểm tra trên một server sạch. Tiêu diệt tay sai Nginx:

  • sudo salt-cloud -d stage-www1

Sau khi đợi sự kiện xử lý, ta có thể xây dựng lại minion.

Ta thường sử dụng file bản đồ cho việc này, nhưng vì ta chỉ đang xây dựng lại một server duy nhất, nên thực sự tốt hơn là sử dụng trực tiếp profile stage-web . Sau đó, ta có thể sử dụng chức năng thực thi Salt của cloud.profile thay vì salt-cloud , cho phép ta thêm cờ --async . Về cơ bản, điều này cho phép ta xây dựng lại server stage-www1 ở chế độ nền khi ta tiếp tục làm việc. Ta sẽ phải nhắm đến chính Salt master của bạn trong lệnh này vì đây là server có cấu hình cloud mà ta cần:

  • sudo salt --async sm cloud.profile stage-web stage-www1

Trong khi nút stage-www1 của ta đang xây dựng lại trong nền, ta có thể tiếp tục.

Cấu hình Tệp /etc/nginx/nginx.conf

Trước tiên, hãy xem file cấu hình Nginx chính, file này sẽ được đặt tại /etc/nginx/nginx.conf trên tay sai của ta . Ta có thể tìm thấy đường dẫn này trong thư files folder trạng thái Nginx:

  • cd /srv/salt/nginx/files/etc/nginx

Ta thực sự sẽ không sửa đổi file này vào lúc này, nhưng ta có thể tự giúp mình và backup bản root ngay bây giờ:

  • sudo cp nginx.conf nginx.conf.orig

Điều này sẽ cung cấp cho ta một điểm tham khảo tốt cho các tùy chỉnh mà ta có thể thực hiện trong tương lai. Ta có thể nhanh chóng xem bất kỳ thay đổi nào ta đã thực hiện bằng lệnh :

  • diff nginx.conf nginx.conf.orig

Trong tương lai, nếu ta thấy mình cần tùy chỉnh cấu hình của Nginx trong các môi trường khác nhau của ta (ví dụ: ta có thể cần đối sánh worker_processes với số lượng CPU trên server production của bạn sau này), ta có thể cần chuyển sang sử dụng mẫu file . Ta không cần file này vào lúc này, vì vậy, là file không phải mẫu, các thay đổi của ta sẽ được mã hóa cứng.

Như ta đã nêu trước đó, ta không cần bất kỳ sửa đổi nào vào lúc này. Tiếp tục nào.

Cấu hình / etc / nginx / sites-available / Template mặc định

Tiếp theo, hãy xem mẫu khối server mặc định của ta . Ta có thể tìm thấy bản root trong folder này:

  • cd /srv/salt/nginx/files/etc/nginx/sites-available

, ta nên sao chép bản root vào vị trí dự phòng trong trường hợp ta cần nó sau này:

  • sudo cp default default.orig

Sau đó, ta có thể đổi tên file để nó có phần mở rộng .jinja . Điều này sẽ nhắc nhở ta một cách trực quan rằng file này là một mẫu chứ không phải là một file có thể sử dụng được:

  • sudo mv default default.jinja

Bây giờ, ta có thể mở file mẫu để thực hiện một số thay đổi:

  • sudo nano default.jinja

Ở đầu file , ta cần bắt đầu sử dụng các tính năng tạo khuôn mẫu của Jinja. Khối server mặc định của ta cần hiển thị các file khác nhau tùy thuộc vào việc web server có chạy sau bộ cân bằng tải hay không.

Khi các kết nối đang được nhận thông qua bộ cân bằng tải, ta muốn web server của bạn hạn chế lưu lượng truy cập của nó vào giao diện riêng tư. Tuy nhiên, khi ta đang ở trong môi trường phát triển, ta không có bộ cân bằng tải, vì vậy ta muốn cung cấp qua giao diện công khai. Ta có thể tạo ra sự khác biệt này với Jinja.

Ta sẽ tạo một biến được gọi là interface chứa giao diện mà ta muốn có địa chỉ. Ta sẽ kiểm tra xem môi trường của minion có được đặt thành “dev” hay không, trong trường hợp đó ta sẽ sử dụng giao diện eth0 . Nếu không, ta sẽ đặt nó thành eth1 , giao diện riêng tư của server . Sau đó, ta sẽ sử dụng hàm module thực thi grains.get để lấy địa chỉ được liên kết với giao diện đã chọn và sử dụng địa chỉ đó làm giá trị cho biến addr . Ta sẽ thêm điều này vào đầu file :

/srv/salt/nginx/files/etc/nginx/sites-available/default.jinja
{%- set interface = 'eth0' if salt['grains.get']('env') == 'dev' else 'eth1' -%} {%- set addr = salt['network.interface_ip'](interface) -%} # You may add here your # server { #       ... # }  . . . 

Tiếp theo, ta có thể chỉnh sửa thêm khối server trong file . Ta có thể sử dụng addr ta cài đặt biến ở phía trên trong listenserver_name chỉ thị. Ta đã xóa IPv6 và các phần server mặc định để hạn chế những gì khối này phục vụ:

/srv/salt/nginx/files/etc/nginx/sites-available/default.jinja
{%- set interface = 'eth0' if salt['grains.get']('env') == 'dev' else 'eth1' -%} {%- set addr = salt['network.interface_ip'](interface) -%}  . . .  server {     listen {{ addr }}:80;      root /usr/share/nginx/html;     index index.html index.htm;      server_name {{ addr }};      location / {         try_files $uri $uri/ =404;     } } 

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

Cấu hình /usr/share/nginx/html/index.html Mẫu

Bây giờ ta có thể chuyển sang index.html . Di chuyển đến folder trên Salt master có chứa file :

  • cd /srv/salt/nginx/files/usr/share/nginx/html

Bên trong, ta cần bắt đầu với cùng một quy trình mà ta đã sử dụng lần trước. Ta nên lưu trữ một bản sao của file root cho mục đích kiểm tra và backup . Sau đó, ta nên đổi tên file để cho biết đây sẽ là một mẫu:

  • sudo cp index.html index.html.orig
  • sudo mv index.html index.html.jinja

Mở file mẫu để ta có thể thực hiện các sửa đổi cần thiết:

  • sudo nano index.html.jinja

Ở trên cùng, ta sẽ đặt một biến khác bằng cách sử dụng Jinja. Ta sẽ sử dụng chức năng module thực thi grains.get để lấy tên server của minion. Ta sẽ lưu trữ điều này trong biến host :

{% set host = salt['grains.get']('host') -%} <!DOCTYPE html> <html>  . . . 

Sau đó, ta sẽ sử dụng giá trị này trong toàn bộ file để ta có thể dễ dàng biết web server nào đang phục vụ các yêu cầu của ta . Thay đổi giá trị <title> trước:

{% set host = salt['grains.get']('host') -%} <!DOCTYPE html> <html> <head> <title>Welcome from {{ host }}</title> . . . 

Hãy thay đổi nội dung thành văn bản này:

. . .  <body> <h1>Welcome to nginx!</h1> <p>Hello!  This is being served from:</p>  <h2>{{ host }}</h2>  </body> </html> 

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

Kiểm tra file trạng thái Nginx

Bây giờ ta đã hoàn thành cấu hình Nginx của bạn . Ta có thể kiểm tra các khía cạnh nhất định của trạng thái đảm bảo rằng nó hoạt động bình thường.

Đầu tiên, ta có thể sử dụng hàm module thực thi state.show_sls để xem cách Salt sẽ diễn giải file trạng thái Nginx của ta . Ta có thể sử dụng server stage-www1 làm mục tiêu. Tuy nhiên, không có gì sẽ thực thi trên server tại thời điểm này:

  • sudo salt stage-www1 state.show_sls nginx

Bạn sẽ nhận lại kết quả trông giống như sau:

Output
stage-www1: ---------- /etc/nginx/nginx.conf: ---------- __env__: base __sls__: nginx file: |_ ---------- source: salt://nginx/files/etc/nginx/nginx.conf |_ ---------- user: root |_ ---------- group: root |_ ---------- mode: 640 - managed |_ ---------- order: 10002 . . .

Nó chủ yếu hiển thị thông tin từ file /srv/salt/nginx/init.sls của ta với một số bổ sung thú vị. Kiểm tra đảm bảo rằng không có lỗi diễn giải nào mà Salt không biết cách đọc lệnh. "Thứ tự" của mỗi phần là một mục tốt khác để kiểm tra. Điều này xác định khi nào mỗi trạng thái riêng lẻ trong file sẽ chạy. Trạng thái đầu tiên sẽ có số thứ tự "10000". Mọi trạng thái bổ sung sẽ được tính từ đó. Lưu ý __env__ khác với env mà ta đặt bằng cách sử dụng ngũ cốc. Ta không sử dụng quan niệm của Salt về môi trường trong hướng dẫn này.

Tiếp theo, ta có thể thực hiện nhanh việc áp dụng file trạng thái của bạn . Ta có thể làm điều này với chức năng state.apply với tùy chọn test=True . Lệnh trông như thế này:

  • sudo salt stage-www1 state.apply nginx test=True

Điều này sẽ cho bạn thấy những thay đổi sẽ được thực hiện nếu tùy chọn test=True bị loại bỏ. Hãy xem đảm bảo rằng các thay đổi có ý nghĩa và Salt có thể diễn giải tất cả các file của bạn một cách chính xác. Trường " Comment " đặc biệt quan trọng vì nó có thể tiết lộ các vấn đề ngay cả trong trường hợp Salt không đánh dấu trạng thái là không thành công.

Nếu quá trình chạy khô không cho thấy sự cố nào , bạn có thể thử áp dụng trạng thái cho tất cả các web server hiện có của bạn bằng lệnh :

  • sudo salt -G 'role:webserver' state.apply nginx

Nếu bạn đã áp dụng trạng thái Nginx cho web server dàn dựng hoặc production của bạn , bạn cần lấy địa chỉ IP nội bộ của chúng. Các trang sẽ không khả dụng trên giao diện công khai:

  • sudo salt-call mine.get 'role:webserver' internal_ip expr_form=grain
Output
local: ---------- stage-www1: ip_address stage-www2: ip_address

Mặt khác, nếu bạn mở rộng web server phát triển của bạn và áp dụng trạng thái Nginx, bạn cần lấy địa chỉ bên ngoài vì:

  • sudo salt-call mine.get 'role:webserver' external_ip expr_form=grain

Bạn có thể kiểm tra server của bạn bằng curl :

  • curl ip_address

Bạn sẽ thấy trang index.html mà ta đã sửa đổi:

Output
<!DOCTYPE html> <html> <head> <title>Welcome from stage-www1</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>Hello! This is being served from:</p> <h2>stage-www1</h2> <p><em>Thank you for using nginx.</em></p> </body> </html>

Như bạn thấy , tên server của minion đã được đặt trong file khi Jinja được hiển thị. Trạng thái Nginx của ta hiện đã hoàn tất.

Kết luận

Đến đây bạn sẽ có trạng thái Nginx đầy đủ chức năng. Điều này sẽ cho phép bạn biến bất kỳ máy nào do Salt kiểm soát thành một web server với các thông số kỹ thuật của bạn một cách nhanh chóng và dễ dàng. Ta sẽ sử dụng điều này như một phần của chiến lược quản lý cơ sở hạ tầng lớn hơn của bạn để dễ dàng xây dựng các web server trong môi trường của ta .

Trong hướng dẫn tiếp theo , ta sẽ tiếp tục và xây dựng trạng thái cho các bộ cân bằng tải sẽ hướng lưu lượng truy cập trước web server của ta . Ta sẽ sử dụng một số kỹ thuật tương tự mà ta đã sử dụng trong hướng dẫn này để làm cho bộ cân bằng tải của ta linh hoạt.


Tags:

Các tin liên quan

Cách thêm module log vào Nginx trên Ubuntu 16.04
2016-10-31
Cách thêm module log vào Nginx trên CentOS 7
2016-10-31
Cách di chuyển web root Nginx đến vị trí mới trên Ubuntu 16.04
2016-07-29
Cách cấu hình Nginx làm web server và reverse-proxy (reverse proxy) cho Apache trên một server Ubuntu 16.04
2016-07-06
Cách thiết lập server block Nginx (server ảo) trên Ubuntu 16.04
2016-05-19
Cách cung cấp các ứng dụng Flask với uWSGI và Nginx trên Ubuntu 16.04
2016-05-19
Cách cung cấp các ứng dụng Flask với Gunicorn và Nginx trên Ubuntu 16.04
2016-05-19
Cách thiết lập Django với Postgres, Nginx và Gunicorn trên Ubuntu 16.04
2016-05-18
Cách cung cấp các ứng dụng Django với uWSGI và Nginx trên Ubuntu 16.04
2016-05-16
Cách cài đặt Nginx trên Ubuntu 16.04
2016-04-21