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 :
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:
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:
. . .  /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 :
. . .  /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:
. . .  /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" 
Outputfiles 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 :
{%- 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 listen và server_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ụ:
{%- 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:
Outputstage-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 
Outputlocal:     ----------     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.
Các tin liên quan
Cách thêm module log vào Nginx trên CentOS 72016-10-31
Cách thêm module log vào Nginx trên Ubuntu 16.04
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 cung cấp các ứng dụng Flask với Gunicorn và Nginx 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 thiết lập server block Nginx (server ảo) 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 tạo chứng chỉ SSL tự ký cho Nginx trong Ubuntu 16.04
2016-04-21
 

