安裝配方 - AWS OpsWorks

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

安裝配方

重要

該 AWS OpsWorks Stacks 服務於 2024 年 5 月 26 日終止使用壽命,並已針對新客戶和現有客戶停用。我們強烈建議客戶盡快將其工作負載移轉至其他解決方案。如果您對移轉有任何疑問,請透過 AWS Re: post 或透過進AWS 階 Support 與 AWS Support 團隊聯絡。

安裝配方會指派給 layer 的安裝生命週期事件,並會在執行個體啟動後執行。他們會執行像是安裝套件、建立組態檔案和啟動服務等任務。安裝程式方法完成執行後, AWS OpsWorks Stacks 會執行部署方法,將任何應用程式部署到新的執行個體。

tomcat::setup

tomcat::setup 配方用於指派給 layer 的安裝生命週期事件。

include_recipe 'tomcat::install' include_recipe 'tomcat::service' service 'tomcat' do action :enable end # for EBS-backed instances we rely on autofs bash '(re-)start autofs earlier' do user 'root' code <<-EOC service autofs restart EOC notifies :restart, resources(:service => 'tomcat') end include_recipe 'tomcat::container_config' include_recipe 'apache2' include_recipe 'tomcat::apache_tomcat_bind'

tomcat::setup 配方基本上就是一個中繼配方。它包含一組處理大部分安裝和設定 Tomcat 之詳細資訊和相關套件的依存配方。tomcat::setup 的第一個部分會執行下列配方。下列配方會在稍後進行討論:

tomcat::setup 的中間部分會啟用並執行 Tomcat 服務:

  • Chef service 資源會在開機時啟用 Tomcat 服務。

  • 廚師 bash 資源運行一個 Bash 腳本來啟動 autofs 守護進程,這對於 Amazon EBS 支持的實例來說是必需的。資源接著會通知 service 資源重新啟動 Tomcat 服務。

    如需詳細資訊,請參閱 autofs (Amazon Linux 適用) 或 Autofs (Ubuntu 適用)。

tomcat::setup 的最後部分會建立組態檔案,安裝及設定前端 Apache 伺服器:

  • tomcat::container_config 配方會建立組態檔案。

  • apache2配方(這是簡寫apache2::default)是一個 AWS OpsWorks 堆棧內置配方,用於安裝和配置 Apache 服務器。

  • tomcat::apache_tomcat_bind 配方會設定 Apache 伺服器,做為 Tomcat 伺服器的前端。

注意

您通常可以透過使用內建配方執行一部分的必要任務,省下時間和精力。此配方使用內建的 apache2::default 配方安裝 Apache,而非從零開始實作。如需如何使用內建配方的另一個範例,請參閱部署配方

下列章節會更詳細的說明 Tomcat 技術指南的安裝配方。如需 apache2 配方的詳細資訊,請參閱 opsworks-cookbooks/apache2

tomcat::install

tomcat::install 配方會安裝 Tomcat 伺服器、OpenJDK 和處理 MySQL 伺服器連線的 Java 連接器程式庫。

tomcat_pkgs = value_for_platform( ['debian', 'ubuntu'] => { 'default' => ["tomcat#{node['tomcat']['base_version']}", 'libtcnative-1', 'libmysql-java'] }, ['centos', 'redhat', 'fedora', 'amazon'] => { 'default' => ["tomcat#{node['tomcat']['base_version']}", 'tomcat-native', 'mysql-connector-java'] }, 'default' => ["tomcat#{node['tomcat']['base_version']}"] ) tomcat_pkgs.each do |pkg| package pkg do action :install end end link ::File.join(node['tomcat']['lib_dir'], node['tomcat']['mysql_connector_jar']) do to ::File.join(node['tomcat']['java_dir'], node['tomcat']['mysql_connector_jar']) action :create end # remove the ROOT webapp, if it got installed by default include_recipe 'tomcat::remove_root_webapp'

配方會執行下列任務:

  1. 根據執行個體的作業系統建立要安裝的套件清單。

  2. 安裝清單中的每個套件。

    廚師軟件包資源使用適當的提供商-yum Amazon Linux 和 apt-get Ubuntu-來處理安裝。套件提供者會將 OpenJDK 做為 Tomcat 的依存安裝,但 MySQL 連接器程式庫必須明確安裝。

  3. 使用 Chef link 資源,在 Tomcat 伺服器的 lib 目錄中建立連結到 JDK 中 MySQL 連接器程式庫的 symlink。

    使用預設屬性值,Tomcat lib 目錄為 /usr/share/tomcat6/lib,MySQL 連接器程式庫 (mysql-connector-java.jar) 則位於 /usr/share/java/

tomcat::remove_root_webapp 配方會移除 ROOT web 應用程式 (預設為 /var/lib/tomcat6/webapps/ROOT),避免某些安全問題。

ruby_block 'remove the ROOT webapp' do block do ::FileUtils.rm_rf(::File.join(node['tomcat']['webapps_base_dir'], 'ROOT'), :secure => true) end only_if { ::File.exists?(::File.join(node['tomcat']['webapps_base_dir'], 'ROOT')) && !::File.symlink?(::File.join(node['tomcat']['webapps_base_dir'], 'ROOT')) } end

only_if 陳述式會確保只有在檔案存在時,配方才會移除他們。

注意

Tomcat 的版本以 ['tomcat']['base_version'] 屬性指定,其在屬性檔案中已設為 6。若要安裝 Tomcat 7,您可以使用自訂 JSON 屬性覆寫屬性。您只需編輯您的堆疊設定並在 Custom Chef JSON (自訂 Chef JSON) 方塊中輸入下列 JSON,或是將其新增至任何現有的自訂 JSON:

{ 'tomcat' : { 'base_version' : 7 } }

自訂 JSON 屬性會覆寫預設屬性,並將 Tomcat 的版本設為 7。如需覆寫屬性的詳細資訊,請參閱覆寫屬性

tomcat::service

tomcat::service 配方會建立 Tomcat 服務定義。

service 'tomcat' do service_name "tomcat#{node['tomcat']['base_version']}" case node[:platform] when 'centos', 'redhat', 'fedora', 'amazon' supports :restart => true, :reload => true, :status => true when 'debian', 'ubuntu' supports :restart => true, :reload => false, :status => true end action :nothing end

配方會使用 Chef service 資源指定 Tomcat 服務名稱 (預設為 tomcat6),並設定 supports 屬性,以定義 Chef 管理服務重新啟動、重新載入和在不同作業系統上狀態命令的方式。

  • true 表示 Chef 可使用 init 指令碼或其他服務提供者執行命令。

  • false 表示 Chef 必須嘗試使用其他方式執行命令。

請注意,action 已設為 :nothing。對於每個生命週期事件, AWS OpsWorks Stacks 都會啟動 Chef 運行以執行適當的配方集。Tomcat 技術指南遵循讓配方建立服務定義,但不重新啟動服務的常見模式。Chef 執行中的其他配方會處理重新啟動,其方式通常為藉由在用來建立組態檔案的 notifies 資源中包含 template 命令。通知為重新啟動服務的一種便利方式,因為他們只會在組態變更時才會執行此作業。此外,當 Chef 執行具有多個服務的重新啟動通知時,Chef 最多只會重新啟動服務一次。這種做法可避免在嘗試重新啟動未完全運作的服務時可能發生的問題。此為 Tomcat 錯誤的常見來源。

必須為任何使用重新啟動通知的 Chef run 定義 Tomcat 服務。因此,tomcat::service 會包含在數個配方中,確保為每一個 Chef run 定義服務。即使 Chef 執行包含多個 tomcat::service 的執行個體,也不會有任何損失,因為 Chef 會確保每個配方只會在每次執行時執行一次,無論其包含多少次在內。

tomcat::container_config

tomcat::container_config 配方會從技術指南範本檔案建立組態檔案。

include_recipe 'tomcat::service' template 'tomcat environment configuration' do path ::File.join(node['tomcat']['system_env_dir'], "tomcat#{node['tomcat']['base_version']}") source 'tomcat_env_config.erb' owner 'root' group 'root' mode 0644 backup false notifies :restart, resources(:service => 'tomcat') end template 'tomcat server configuration' do path ::File.join(node['tomcat']['catalina_base_dir'], 'server.xml') source 'server.xml.erb' owner 'root' group 'root' mode 0644 backup false notifies :restart, resources(:service => 'tomcat') end

配方首先會呼叫 tomcat::service,其將於必要時定義服務。大量的配方皆由兩個 template 資源組成,這兩個資源會各自從其中一個技術指南範本檔案建立組態檔案、設定檔案屬性,並通知 Chef 重新啟動服務。

Tomcat 環境資訊檔案

第一個 template 資源會使用 tomcat_env_config.erb 範本檔案建立 Tomcat 環境資訊檔案,用於設定像是 JAVA_HOME 等環境變數。預設檔案名稱為 template 資源的引數。tomcat::container_config 會使用 path 屬性覆寫預設值及命名組態檔 /etc/sysconfig/tomcat6 (Amazon Linux) 或 /etc/default/tomcat6 (Ubuntu)。template 資源也會指定檔案的擁有者、群組和模式設定,並指示 Chef 不要建立備份檔案。

若您查看來源碼,通常會有三種版本的 tomcat_env_config.erb,每一種都位於 templates 目錄中的不同子目錄內。ubuntuamazon 目錄包含其各自作業系統的範本。default 資料夾則包含僅有一行註解的 dummy 範本,僅會在您嘗試在使用不支援作業系統的執行個體上執行此配方時使用。tomcat::container_config 配方不需要指定要使用何種 tomcat_env_config.erb。Chef 會自動根據檔案精確性中描述的規則,為執行個體的作業系統挑選適當的目錄。

此範例的 tomcat_env_config.erb 檔案大部分由註解組成。若要設定其他環境變數,只需要取消註解適當的行,並提供您喜好的值即可。

注意

任何可能變更的組態設定都應定義為屬性,而非在範本中硬式編碼。如此一來,您便不需要重新撰寫範本以變更設定;您可以直接覆寫屬性。

Amazon Linux 範本只會設定一個環境變數,如下列摘要所示。

... # Use JAVA_OPTS to set java.library.path for libtcnative.so #JAVA_OPTS="-Djava.library.path=/usr/lib" JAVA_OPTS="${JAVA_OPTS} <%= node['tomcat']['java_opts'] %>" # What user should run tomcat #TOMCAT_USER="tomcat" ...

JAVA_OPTS 可用來指定 Java 選項 (例如程式庫路徑)。若使用預設屬性值,範本便不會為 Amazon Linux 設定任何 Java 選項。您可以藉由覆寫 ['tomcat']['java_opts'] 屬性 (例如:使用自訂 JSON 屬性),來設定您自己的 Java 選項。如需範例,請參閱建立堆疊

Ubuntu 範本會設定數個環境變數,如下列範本摘要所示。

# Run Tomcat as this user ID. Not setting this or leaving it blank will use the # default of tomcat<%= node['tomcat']['base_version'] %>. TOMCAT<%= node['tomcat']['base_version'] %>_USER=tomcat<%= node['tomcat']['base_version'] %> ... # Run Tomcat as this group ID. Not setting this or leaving it blank will use # the default of tomcat<%= node['tomcat']['base_version'] %>. TOMCAT<%= node['tomcat']['base_version'] %>_GROUP=tomcat<%= node['tomcat']['base_version'] %> ... JAVA_OPTS="<%= node['tomcat']['java_opts'] %>" <% if node['tomcat']['base_version'].to_i < 7 -%> # Unset LC_ALL to prevent user environment executing the init script from # influencing servlet behavior. See Debian bug #645221 unset LC_ALL <% end -%>

若使用預設屬性值,範本便會設定 Ubuntu 環境變數,如下所示:

  • 代表 Tomcat 使用者和群組的 TOMCAT6_USERTOMCAT6_GROUP 都已設為 tomcat6

    若您將 ['tomcat']['base_version'] 設為 tomcat7,變數名稱會解析為 TOMCAT7_USERTOMCAT7_GROUP,並且都會設為 tomcat7

  • JAVA_OPTS 已設定為 -Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC

    • -Djava.awt.headless 設為 true 會向圖形引擎通知執行個體沒有標題並且也沒有主控台,表示特定圖形應用程式的錯誤行為。

    • -Xmx128m 可確保 JVM 具有足夠的記憶體資源,此範例為 128MB。

    • -XX:+UseConcMarkSweepGC 指定同時標記整理記憶體回收,協助限制記憶體回收造成的暫停。

      如需詳細資訊,請參閱 Concurrent Mark Sweep Collector Enhancements

  • 若 Tomcat 的版本低於 7,範本會取消設定處理 Ubuntu 錯誤的 LC_ALL

注意

若使用預設屬性,部分環境變數便會設為其預設值。但是,明確將環境變數設為屬性表示您可以定義自訂 JSON 屬性覆寫預設屬性,並提供自訂的值。如需覆寫屬性的詳細資訊,請參閱覆寫屬性

如需完整的範本檔案,請參閱來源碼

Server.xml 組態檔案

第二個 template 資源會使用 server.xml.erb 建立 system.xml 組態檔,設定 servlet/JSP 容器。server.xml.erb 沒有包含任何作業系統限定設定,因此它會位於 template 目錄的 default 子目錄中。

範本使用者使用標準設定,但它也可以為 Tomcat 6 或 Tomcat 7 建立 system.xml 檔案。例如,下列來自範本的伺服器區段的程式碼會為指定的版本適當設定接聽程式。

<% if node['tomcat']['base_version'].to_i > 6 -%> <!-- Security listener. Documentation at /docs/config/listeners.html <Listener className="org.apache.catalina.security.SecurityListener" /> --> <% end -%> <!--APR library loader. Documentation at /docs/apr.html --> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html --> <Listener className="org.apache.catalina.core.JasperListener" /> <!-- Prevent memory leaks due to use of particular java/javax APIs--> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <% if node['tomcat']['base_version'].to_i < 7 -%> <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html --> <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" /> <% end -%> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <% if node['tomcat']['base_version'].to_i > 6 -%> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <% end -%>

範本使用屬性,而非硬式編碼設定,讓您可以藉由定義自訂 JSON 屬性,輕易變更設定。例如:

<Connector port="<%= node['tomcat']['port'] %>" protocol="HTTP/1.1" connectionTimeout="20000" URIEncoding="<%= node['tomcat']['uri_encoding'] %>" redirectPort="<%= node['tomcat']['secure_port'] %>" />

如需詳細資訊,請參閱來源碼

tomcat::apache_tomcat_bind

tomcat::apache_tomcat_bind 配方會啟用 Apache 伺服器做為 Tomcat 的前端,接受傳入的請求,並將他們轉遞至 Tomcat 並將回應傳回用戶端。此範例使用 mod_proxy 做為 Apache 代理/閘道。

execute 'enable mod_proxy for apache-tomcat binding' do command '/usr/sbin/a2enmod proxy' not_if do ::File.symlink?(::File.join(node['apache']['dir'], 'mods-enabled', 'proxy.load')) || node['tomcat']['apache_tomcat_bind_mod'] !~ /\Aproxy/ end end execute 'enable module for apache-tomcat binding' do command "/usr/sbin/a2enmod #{node['tomcat']['apache_tomcat_bind_mod']}" not_if {::File.symlink?(::File.join(node['apache']['dir'], 'mods-enabled', "#{node['tomcat']['apache_tomcat_bind_mod']}.load"))} end include_recipe 'apache2::service' template 'tomcat thru apache binding' do path ::File.join(node['apache']['dir'], 'conf.d', node['tomcat']['apache_tomcat_bind_config']) source 'apache_tomcat_bind.conf.erb' owner 'root' group 'root' mode 0644 backup false notifies :restart, resources(:service => 'apache2') end

若要啟用 mod_proxy,您必須啟用 proxy 模組及通訊協定式模組。您有兩個通訊協定模組選項:

兩種配方的 execute 資源都會執行 a2enmod 命令,透過建立必要的 symlink 啟用指定的模組:

  • 第一個 execute 資源會啟用 proxy 模組。

  • 第二個 execute 資源會啟用通訊協定模組,根據預設設為 proxy_http

    若您要使用 AJP,您可以定義自訂 JSON 覆寫 apache_tomcat_bind_mod 屬性,將其設為 proxy_ajp

apache2::service配方是定義 Apache 服務的「 AWS OpsWorks 堆疊」內建配方。如需詳細資訊,請參閱 St AWS OpsWorks acks GitHub 儲存庫中的配方

template 資源使用 apache_tomcat_bind.conf.erb 建立根據預設名為 tomcat_bind.conf 的組態檔案。它會將檔案置放在 ['apache']['dir']/.conf.d 目錄中。['apache']['dir'] 屬性會在內建的 apache2 屬性檔案中定義,並根據預設設為 /etc/httpd (Amazon Linux) 或 /etc/apache2 (Ubuntu)。若 template 資源建立或變更組態檔案,notifies 命令會排程 Apache 服務重新啟動。

<% if node['tomcat']['apache_tomcat_bind_mod'] == 'proxy_ajp' -%> ProxyPass <%= node['tomcat']['apache_tomcat_bind_path'] %> ajp://localhost:<%= node['tomcat']['ajp_port'] %>/ ProxyPassReverse <%= node['tomcat']['apache_tomcat_bind_path'] %> ajp://localhost:<%= node['tomcat']['ajp_port'] %>/ <% else %> ProxyPass <%= node['tomcat']['apache_tomcat_bind_path'] %> http://localhost:<%= node['tomcat']['port'] %>/ ProxyPassReverse <%= node['tomcat']['apache_tomcat_bind_path'] %> http://localhost:<%= node['tomcat']['port'] %>/ <% end -%>

該模板使用ProxyPass和指ProxyPassReverse令來配置用於在 Apache 和 Tomcat 之間傳遞流量的端口。因為兩個伺服器都位於相同的執行個體上,他們可以使用 localhost URL,並且根據預設都會設為 http://localhost:8080