返回文章列表

Chef 自動化佈署 Nginx 伺服器與組態驗證

本文介紹如何使用 Chef 自動化佈署和驗證 Nginx 伺服器組態,包含 Cookbook 建立、食譜撰寫、範本檔案設定、InSpec 驗證及 Test Kitchen 測試等步驟,涵蓋伺服器管理、維護及最佳實踐,並提供程式碼範例和詳細步驟說明。

DevOps Web 開發

Chef 自動化框架能有效簡化 Nginx 伺服器的佈署和管理流程。本文示範如何建立 Nginx Cookbook,撰寫安裝、組態 Nginx 的食譜,並利用 ERB 範本定義組態檔案內容。同時,引入 InSpec 工具進行組態驗證,確保伺服器狀態符合預期。最後,整合 Test Kitchen 進行自動化測試,提升佈署效率和程式碼可靠性,符合現代 DevOps 的最佳實踐。

Chef 自動化佈署 Nginx 伺服器

Chef 是一種強大的自動化工具,用於簡化 IT 基礎設施的管理和佈署。本文將介紹如何使用 Chef 自動化佈署 Nginx 伺服器,包括安裝、組態和啟動服務。

建立 Nginx Cookbook

首先,我們需要建立一個 Nginx cookbook,用於定義 Nginx 伺服器的組態和佈署步驟。

# Recipe:: default
include_recipe 'nginx::webserver'
include_profile 'nginx::nginx'

上述程式碼中,include_recipe 用於引入 webserver.rb 食譜,而 include_profile 用於引入 nginx 組態檔案。

內容解密:

  • include_recipeinclude_profile 是 Chef 中的資源,用於引入其他食譜和組態檔案。
  • nginx::webserver 是我們將要建立的食譜,用於定義 Nginx 伺服器的組態和佈署步驟。

編寫 Webserver 食譜

接下來,我們需要編寫 webserver.rb 食譜,用於安裝和組態 Nginx 伺服器。

# Cookbook:: nginx
# Recipe:: webserver

package 'nginx' 
package 'curl'

directory '/etc/nginx/ssl' do 
  owner 'root'
  group 'root'
  mode '0755'
  action :create
end

openssl_x509_certificate '/etc/nginx/ssl/mycert.pem' do
  common_name 'node[:fqdn]'
  org 'Chef'
  org_unit 'Lab'
  country 'US'
  mode '0600'
end

template '/etc/nginx/nginx.conf' do 
  source 'nginx.conf.erb'
  owner 'root'
  group 'root'
  mode '0644'
  notifies :restart, 'service[nginx]', :delayed
  action :create
end

template '/etc/nginx/sites-available/default' do
  source 'server.erb'
  owner 'root'
  group 'root'
  mode '0644'
  notifies :restart, 'service[nginx]', :delayed
  action :create
end

template '/var/www/html/index.html' do
  source 'index.erb'
  owner 'root'
  group 'root'
  mode '0644'
  action :create
end

service 'nginx' do 
  action [:enable, :start]
end

service 'nginx' do
  subscribes :reload, 'file[/etc/nginx/ssl/mycert.pem]', :immediately
end

內容解密:

  1. 使用 package 資源安裝 Nginx 和 curl 軟體包。
  2. 使用 directory 資源建立 /etc/nginx/ssl 目錄,用於存放 SSL 證書。
  3. 使用 openssl_x509_certificate 資源產生 SSL 證書。
  4. 使用 template 資源建立 Nginx 組態檔案和靜態 HTML 檔案。
    • source 指定範本檔案的來源。
    • notifies 指定當範本檔案變更時,重新啟動 Nginx 服務。
  5. 使用 service 資源啟動和啟用 Nginx 服務,並在 SSL 證書變更時重新載入服務。

建立範本檔案

Chef 使用範本檔案來定義組態檔案和靜態檔案的內容。我們需要建立三個範本檔案:nginx.conf.erbserver.erbindex.erb

nginx.conf.erb

user root;
worker_processes auto;
pid /run/nginx.pid;
events {
  worker_connections 768;
}
http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 65;
  types_hash_max_size 2048;
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  ssl_protocols TLSv1.2 TLSv1.3;
  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;
  include /etc/nginx/sites-enabled/*;
}

server.erb

server {
  listen 443 ssl;
  server_name <%= node[:fqdn] %>;
  ssl_certificate /etc/nginx/ssl/mycert.pem;
  ssl_certificate_key /etc/nginx/ssl/mycert.key;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl on;
  root /var/www/html;
}

index.erb

<html>
<head>
<title>Nginx Site Created by Chef</title>
</head>
<body>
<h3>This is Nginx by Chef</h3>
<p><b>Hostname:</b> <%= node[:hostname] %></p>
<p><b>FQDN:</b> <%= node[:fqdn] %></p>
<p><b>IP Address:</b> <%= node[:ipaddress] %></p>
<p><b>Platform:</b> <%= node[:platform] %></p>
</body>
</html>

內容解密:

  • 使用 ERb(Embedded RuBy)範本語言來定義範本檔案的內容。
  • <%= node[:attribute] %> 用於插入節點的屬性值,例如主機名、FQDN、IP 地址和平台。

Chef 自動化佈署與驗證 NGINX 組態

在現代 DevOps 實踐中,自動化佈署和組態驗證是確保系統穩定性和安全性的關鍵步驟。本文將探討如何使用 Chef 進行 NGINX 的自動化佈署與組態驗證,並介紹相關的技術細節和最佳實踐。

Chef 範本資源的使用

Chef 提供了強大的範本資源(template resource),允許管理員使用 Ruby 的 ERb 範本語言來建立動態組態檔案。下面是一個典型的 Chef 範本資源範例,用於組態 NGINX:

template '/etc/nginx/nginx.conf' do
  source 'nginx.conf.erb'
  owner 'root'
  group 'root'
  mode '0644'
  notifies :restart, 'service[nginx]', :delayed
  action :create
end

內容解密:

  1. template '/etc/nginx/nginx.conf' do: 定義一個範本資源,用於在節點上建立 /etc/nginx/nginx.conf 檔案。
  2. source 'nginx.conf.erb': 指定範本檔案的來源,這裡是 nginx.conf.erb,通常位於 ./cookbooks/nginx/templates/ 目錄下。
  3. owner 'root'group 'root': 設定檔案的擁有者和群組為 root
  4. mode '0644': 設定檔案的許可權為 0644,即擁有者可讀寫,群組和其他使用者唯讀。
  5. notifies :restart, 'service[nginx]', :delayed: 當範本檔案發生變化時,通知 NGINX 服務重新啟動,:delayed 表示延遲執行,直到 Chef 執行結束時才重新啟動服務。
  6. action :create: 定義範本資源的操作,這裡是建立檔案。

建立 Chef InSpec 組態檔

Chef InSpec 是用於驗證系統組態和安全性的工具。組態檔案(profile)包含了多個控制項(control),用於檢查系統狀態是否符合預期。下面是一個 NGINX 組態檔的範例:

control 'nginx-config' do
  impact 0.7
  title 'Nginx configuration'
  desc 'Nginx configuration'
  describe port(80) do
    it { should_not be_listening }
  end
  describe port(443) do
    it { should be_listening }
  end
  describe package('nginx') do
    it { should be_installed }
  end
  describe http('https://localhost:443/', ssl_verify: false) do
    its('status') { should cmp 200 }
    its('body') { should match /Nginx Site Created by Chef/ }
  end
end

control 'nginx-security' do
  impact 1.0
  title 'Nginx TLS security'
  desc 'Do not support TLSv1.1'
  describe ssl(port: 443).protocols('tls1.1') do
    it { should_not be_enabled }
  end
  describe ssl(port: 443).protocols('tls1.2') do
    it { should be_enabled }
  end
end

內容解密:

  1. control 'nginx-config' do: 定義一個名為 nginx-config 的控制項,用於檢查 NGINX 的基本組態。
  2. impact 0.7: 設定該控制項的重要性,範圍從 0.0(低)到 1.0(高)。
  3. describe port(80) dodescribe port(443) do: 分別檢查埠 80 和 443 的監聽狀態。
  4. describe package('nginx') do: 檢查 NGINX 軟體包是否已安裝。
  5. describe http('https://localhost:443/', ssl_verify: false) do: 對 NGINX 的 HTTPS 組態進行檢查,包括傳回狀態碼和頁面內容。
  6. control 'nginx-security' do: 定義另一個控制項,用於檢查 NGINX 的 TLS 組態,確保不支援 TLSv1.1 但支援 TLSv1.2。

套用和測試 Chef 組態

使用 chef-run 命令可以將 Chef 組態套用到目標節點,並進行驗證:

$ chef-run ubuntu05.devops.lab recipes/default.rb -i ~/.ssh/id_rsa --user root

執行後,Chef 將自動安裝 chef-client 元件並組態目標節點。之後,可以使用 inspec exec 命令單獨執行 InSpec 組態檔進行驗證:

$ inspec exec compliance/profiles/nginx -t ssh://root@ubuntu05
$ inspec exec compliance/profiles/nginx -t ssh://root@rpi4

這兩個命令將對指定的節點執行 InSpec 組態檔中的檢查,並輸出結果。

使用 Test Kitchen 進行測試

當你使用 -k dokken 旗標建立你的 cookbook 時,Chef 會在 ~/chef-repo/cookbooks/nginx 目錄的根目錄下建立一個 kitchen.yml 檔案,該檔案設定為使用 Docker 在本地端測試你的設定。讓我們來看看它是如何運作的。

Test Kitchen 在你安裝 Chef Workstation 時就已經被安裝,並且它具有能夠讓你使用 Docker、Vagrant,甚至是 AWS 和 Azure 中的雲端帳戶進行本地測試的外掛。Dokken(Docker)版本需要在你的工作站上安裝 Docker。Vagrant 版本需要 Vagrant 應用程式和像 VirtualBox 這樣的工具來建立本地虛擬機器,以便你可以測試例項。

在本例中,你將使用 Docker。如果你之前沒有在你的 Linux 工作站上安裝 Docker,請執行以下命令:

$ sudo apt install docker.io docker-compose

當安裝完成後,將你的使用者新增至系統上的 docker 群組:

$ sudo usermod -aG docker $USER

登出並重新登入以啟用該群組設定,然後執行快速測試以確保你的使用者有許可權執行 Docker:

$ docker ps

Test Kitchen with Dokken 會啟動更像真實 VM 的容器,以便你可以進行全面的測試。你也可以佈署你的程式碼到多種 Linux 發行版上,Test Kitchen 將建立所有東西,套用你的程式碼,並一步完成測試。從 DevOps 的角度來看,這使得快速的程式碼迭代成為可能,並且所產生的程式碼可以自信地套用到實際的測試和生產伺服器上。

設定 kitchen.yml 檔案

檢視 ~/chef-repo/cookbooks/nginx 目錄根目錄下的 kitchen.yml 檔案。將其修改為類別似於清單 8-10 中的範例。

清單 8-10. 一個範例 kitchen.yml 檔案

---
driver:
  name: dokken
  privileged: true # 允許 systemd 服務
chef_version: latest
provisioner:
  name: dokken
transport:
  name: dokken
verifier:
  name: inspec
platforms:
  - name: ubuntu-20.04
    driver:
      image: dokken/ubuntu-20.04
      pid_one_command: /bin/systemd
    intermediate_instructions:
      - RUN /usr/bin/apt-get update
#  - name: centos-8
#    driver:
#      image: dokken/centos-8
#      pid_one_command: /usr/lib/systemd/systemd
suites:
  - name: default
    run_list:
      - recipe[nginx::default]
    verifier:
      inspec_tests:
        - compliance/profiles/nginx
    attributes:
      audit:
        reporter: 'cli'

內容解密:

此範例 kitchen.yml 檔案進行了幾項修改,包括告訴 Test Kitchen 以特權模式建立和執行容器、使用最新版本的 chef-client,以及使用之前建立的 profile。此版本也註解掉了 CentOS 的設定,因為 webserver.rb recipe 不包含處理 Ubuntu 和 Red Hat Linux 之間差異的邏輯。

  • driverprovisionertransport 元素都被設定為 dokken,這將處理 Test Kitchen 如何建立容器和設定網路。
  • verifier 被設定為 inspec。在 suites 部分中,Test Kitchen 有一個設定為 recipe[nginx::default]run_list(分配給節點的 cookbooks),這將套用你的 default.rbwebserver.rb recipes。它還有一個設定為你的 compliance/profiles/nginx profile 相對路徑的 inspec_tests 值。

執行 Test Kitchen

要使其運作,你需要在工作站上執行 Docker。如果已設定好,請從 ./nginx 目錄的根目錄執行以下命令:

$ cookstyle -a
$ kitchen test

第一個命令使用 Cookstyle 檢查你的程式碼;第二個命令建立一個 Ubuntu 20.04 映象,套用你的兩個 cookbook recipes,執行 InSpec profile 掃描,如果一切正確,則關閉並銷毀所有東西。在此過程中,你將看到 Chef 在 Test Kitchen 執行時採取的操作。

分步驟執行 Test Kitchen

你可以將這些步驟分成多個單獨的步驟:建立、融合(套用你的 Chef 程式碼)、驗證和銷毀測試環境:

$ kitchen create
$ kitchen converge
$ kitchen verify
$ kitchen destroy

一步一步地執行這些步驟可以讓你重新執行 convergeverify 命令,以更新和重新驗證你的程式碼。這是測試驅動開發的一個關鍵原則,也是現代 DevOps 團隊的常見做法。

第 9 章:伺服器管理和維護

在前面的章節中,你學習瞭如何佈署各種伺服器和工具,以使你的 DevOps 試驗環境成為一個真正有用的環境,用於測試幾乎任何現代軟體技術。隨著時間的推移,管理這些系統是任何環境(無論是試驗環境還是企業環境)的一個關鍵方面。本章將介紹一些維護和保護試驗環境的最佳實踐,就像你作為 DevSecOps 團隊的一員一樣。

在本章中,你將使用各種工具來圖形化地管理多個系統,並學習如何備份伺服器和資料函式庫,以及如何使用 Ansible 和 Chef 等自動化工具,以及 GitHub(或 GitLab)來進一步定義你的基礎設施即程式碼。

系統管理和維護的關鍵是可見性。能夠確切知道安裝了什麼、正在執行什麼、儲存空間有多少可用等,都應該在不需要登入每個節點的情況下實作。