1. 程式人生 > >Chef學習筆記(一)--基礎知識與安裝配置

Chef學習筆記(一)--基礎知識與安裝配置

Chef 概念 安裝 配置 示例

通常Chef由三部分組成:Workstation、Chef Server、Chef Node。
技術分享圖片

  • Workstation是進行日常工作的機器,需安裝Chef Development Kit,用來編寫cookbooks,管理Chef Server和Node。
  • Chef Server是一個中央倉庫,存儲著cookbooks以及它管理的Node信息。
  • Node是Chef Server管理的機器,即通過Chef進行配置、部署應用的機器,需安裝chef-client Agent。

    術語

  • Ruby Chef使用的語言
  • chef-repo Workstation上的一個目錄,用來存儲Cookbooks、Roles、Data bags、Environments等,可執行以下命令創建其目錄結構:
    $ chef generate repo REPO_NAME
  • Cookbooks A cookbook is the fundamental unit of configuration and policy distribution. 包含recipes, attributes, files, templates, libraries, custom resources等,即定義一系列資源、配置的代碼單元。可執行如下命令創建cookbook:
    $ chef generate cookbook cookbooks/learn_chef
  • Recipes 最基本的配置元素,位於cookbook的recipes目錄內,用來定義Node的資源,可調用cookbook內定義的其他資源,也可依賴其他的recipe。
  • Attributes Node屬性,有6種類型:default、force_default、normal、override、force_override、automatic;可以在5個位置定義:Nodes(安裝chef-client時其中包含ohai工具,它負責收集attribute,稱為automatic attribute,比如ipaddress、hostname、fqdn)、Attribute files、Recipes、Environments、Roles,Roles和Environments中僅允許使用default和override兩種類型,這樣組合起來產生了15個優先級(1+5+5+2+2),具體請參見官方文檔Attribute Precedence。
    一個屬性文件的例子:
    default[‘apache‘][‘dir‘]          = ‘/etc/apache2‘
    default[‘apache‘][‘listen_ports‘] = [ ‘80‘,‘443‘ ]

    說明:default為屬性類型,node object是一個hash table,屬性名可以任意嵌套。
    上例隱式使用了node object(node),也可以在定義時增加上:

    node.default[‘apache‘][‘dir‘]          = ‘/etc/apache2‘
    node.default[‘apache‘][‘listen_ports‘] = [ ‘80‘,‘443‘ ]

    定義的Attribute可在templates、recipes等中引用。

  • Files 文件資源,有三種文件類型:
    1. cookbook_file 源文件在cookbook的files目錄下,將其部署到Node指定位置
      cookbook_file ‘/var/www/customers/public_html/index.php‘ do  
      source ‘index.php‘  
      owner ‘web_admin‘  
      group ‘web_admin‘  
      mode ‘0755‘  
      action :create  
      end
    2. file 沒有源文件,而是直接定義文件的內容
      file ‘/var/www/customers/public_html/index.php‘ do  
      content ‘<html>This is a placeholder for the home page.</html>‘  
      mode ‘0755‘  
      owner ‘web_admin‘  
      group ‘web_admin‘  
      end
    3. remote_file 將遠程文件部署到Node
      remote_file ‘/var/www/customers/public_html/index.php‘ do  
      source ‘http://somesite.com/index.php‘  
      owner ‘web_admin‘  
      group ‘web_admin‘  
      mode ‘0755‘  
      action :create  
      end
  • Template 一種特殊類型的file -- Embedded Ruby (ERB) template,其內可以包含Ruby表達式和語句。Template文件應放在cookbook的templates目錄下,通常采用目標文件名加.erb的命名方式。
    一個例子template - sudoers.erb,其中引用了automatic attribute - fqdn,使用了變量sudoers_groups、sudoers_users:
    #  
    # /etc/sudoers  
    #  
    # Generated by Chef for <%= node[‘fqdn‘] %>  
    #    
    Defaults        !lecture,tty_tickets,!fqdn    
    # User privilege specification  
    root          ALL=(ALL) ALL    
    <% @sudoers_users.each do |user| -%>  
    <%= user %>   ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL  
    <% end -%>    
    # Members of the sysadmin group may gain root privileges  
    %sysadmin     ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL    
    <% @sudoers_groups.each do |group| -%>  
    # Members of the group ‘<%= group %>‘ may gain root privileges  
    %<%= group %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL  
    <% end -%>

    在recipe中調用template並引用屬性為變量賦值:

    template ‘/etc/sudoers‘ do  
    source ‘sudoers.erb‘  
    mode ‘0440‘  
    owner ‘root‘  
    group ‘root‘  
    variables({  
    sudoers_groups: node[‘authorization‘][‘sudo‘][‘groups‘],  
    sudoers_users: node[‘authorization‘][‘sudo‘][‘users‘]  
    })  
    end

    屬性文件attributes/default.rb:

    default[‘authorization‘][‘sudo‘][‘groups‘] = [ ‘sysadmin‘, ‘wheel‘, ‘admin‘ ]  
    default[‘authorization‘][‘sudo‘][‘users‘]  = [ ‘jerry‘, ‘greg‘]
  • Library 位於cookbook的/libraries目錄下,可以使用任意的Ruby代碼,用來創建自定義類或模塊,連接數據庫等。
  • Resources Chef內建支持的資源,recipe內使用最多的部分,可以執行安裝package,配置service,訪問directory、文件系統,創建group和user,運行命令(execute),執行ruby代碼等等。
  • Custom Resources 可以擴展Chef來增加你自己的資源,比如管理website。定義文件位於cookbook的resources目錄下。
  • Policy Policy maps business and operational requirements, process, and workflow to settings and objects stored on the Chef server,即存儲Cookbooks、Roles、Data Bags、Environments、Clients。
  • Data Bags data bag是Json格式存儲的全局變量,位於chef-repo的data_bags目錄下。
    創建Data Bags文件夾admins:
    $ knife data bag create admins

    創建data bag item “charlie.json”:

    $ knife data bag create admins charlie

    內容如下:

    {  
    "id": "charlie",  
    "uid": 1005,  
    "gid": "ops",  
    "shell": "/bin/zsh",  
    "comment": "Crazy Charlie"  
    }

    在recipe中調用:

    charlie = search(:admins, "id:charlie").first
  • Roles 定義服務類型,比如“web server”, “database server”,可以統一設置run-list、attributes等。Role定義支持兩種格式Ruby和JSON,位於chef-repo的roles目錄下。
    {  
    "name": "web",  
    "description": "Web server role.",  
    "json_class": "Chef::Role",  
    "default_attributes": {  
     "chef_client": {  
       "interval": 300,  
       "splay": 60  
     }  
    },  
    "override_attributes": {  
    },  
    "chef_type": "role",  
    "run_list": ["recipe[chef-client::default]",  
                "recipe[chef-client::delete_validation]",  
                "recipe[learn_chef_httpd::default]"  
    ],  
    "env_run_lists": {  
      "production": [],  
      "preprod": []  
    }  
    }  

    設定Node的run-list:

    $ knife node run_list set node1-centos "role[web]"
  • Environments 起初每個組織有一個稱為_default的環境,這個環境不能被修改或刪除。實際應用中可能會創建production、testing、development等環境來滿足不同的需要。Environment定義支持Ruby和Json兩種格式,位於chef-repo的environments目錄下。
    下例設置了dev環境的default_attributes:
    name ‘dev‘  
    description ‘The development environment‘  
    cookbook_versions  ‘couchdb‘ => ‘= 11.0.0‘  
    default_attributes ‘apache2‘ => { ‘listen_ports‘ => [ ‘80‘, ‘443‘ ] }  

    Chef Tool

  • knife 最常用的命令行工具,用來管理chef-repo和Chef Server。Chef本身提供的很多命令也是調用了Knife。
  • Kitchen Cookbooks測試工具
  • Berkshelf Cookbooks依賴管理工具
  • ChefSpec resources和recipes測試工具
  • Ohai 偵測Node屬性的工具

講了這麽多,趕緊擼起袖子安裝環境。先到官網Chef Downloads下載Chef Client、Chef Server、Chef DK安裝包。我使用的操作系統為CentOS7,安裝包均為rpm。

安裝Chef Server

先決條件

  • 為了Chef Server能夠發送郵件,需要配置好郵件agent
  • Chef Server使用RabbitMQ,與Apache Qpid沖突,需禁用Apache Qpid

配置Hostname

Chef server的hostname必須使用FQDN(fully qualified domain name)或者IP地址。在生產環境,FQDN應能被DNS解析,在測試環境,可以將hostname添加到/etc/hosts文件中。如未配置hostname,即使用默認的localhost,只本機才能正常訪問。

# hostname ‘mychefserver.example.com‘
# echo "mychefserver.example.com" | tee /etc/hostname
# echo -e "127.0.0.2 `hostname` `hostname -s`" | tee -a /etc/hosts

安裝Chef Server和Management Console

Management Console是Chef Server的Web管理控制臺(25個Node內免費)。

# rpm -Uvh chef-server-core-12.12.0+20170208114120-1.el7.x86_64.rpm
# chef-server-ctl install chef-manage
# chef-server-ctl reconfigure
# chef-manage-ctl reconfigure

直接運行chef-server-ctl install可查看支持的其他服務器端插件。
說明:執行chef-server-ctl help,可查看chef-server-ctl支持的命令,執行chef-server-ctl <command> -h 可查看命令的語法及參數。

證書

Chef Server對於所有請求默認啟用SSL驗證,在安裝Chef Server時自動生成了自簽名證書,證書和私鑰位於/var/opt/opscode/nginx/ca目錄下,名稱為FQDN.crt和FQDN.key。
Chef Server也可以使用已有的證書,編輯/etc/opscode/chef-server.rb文件,添加如下內容,指定證書位置:

nginx[‘ssl_certificate‘]  = "/etc/pki/tls/certs/your-host.crt"  
nginx[‘ssl_certificate_key‘]  = "/etc/pki/tls/private/your-host.key"

然後執行:

# chef-server-ctl reconfigure

為了安全,應定期更新證書,先停止chef server:

# chef-server-ctl stop

然後刪除原有證書$FQDN.crt和$FQDN.key,如果使用了自定義證書,請用同樣工具再生成。然後再運行:

# chef-server-ctl reconfigure
# chef-server-ctl start

驗證安裝

執行以下命令:

# chef-server-ctl test

創建用戶

命令格式如下:

# chef-server-ctl user-create USER_NAME FIRST_NAME LAST_NAME EMAIL ‘PASSWORD‘ --filename FILE_NAME

執行命令後會自動生成用戶的private key,指定--filename選項保存private key到文件,否則會輸出到屏幕。
Example:

# chef-server-ctl user-create stevedanno Steve Danno [email protected] ‘abc123‘ --filename /path/to/stevedanno.pem

創建organization

命令格式如下:

# chef-server-ctl org-create short_name ‘full_organization_name‘ --association_user user_name --filename ORGANIZATION-validator.pem

其中short_name不能包含大寫字母,--association_user指定組織的管理員用戶。執行命令後會自動生成組織的private key,--filename定義key保存位置。
Example:

# chef-server-ctl org-create 4thcoffee ‘Fourth Coffee, Inc.‘ --association_user stevedanno --filename /path/to/4thcoffee-validator.pem

創建組織時如未指定選項--association_user,可以執行以下命令關聯用戶,可以為組織添加多個用戶,增加-a選項設定為管理員

# chef-server-ctl org-user-add 4thcoffee jason -a

訪問Management Console可以使用FQDN或IP,比如:https://mychefserver.example.com 或https://192.168.1.10.

安裝Workstation

Chef development kit包含chef-client、Ruby,以及一些工具,比如Kitchen、Berkshelf、ChefSpec。

安裝Chef DK

# rpm -Uvh chefdk-1.2.22-1.el7.x86_64.rpm

Verify

$ chef verify

輸出這樣的結果:Verification of component ‘....‘ succeeded
查看幫助

$ chef -h

配置Ruby

查看Ruby安裝位置

$ which ruby

為了使用Chef DK內嵌的Ruby,執行以下命令將Chef DK路徑增加到環境變量PATH:

$ echo ‘eval "$(chef shell-init bash)"‘ >> ~/.bash_profile

配置chef-repo

創建chef-repo

$ chef generate repo chef-repo

創建.chef目錄

$ mkdir chef-repo/.chef

因為Workstation要與Server交互,需登錄Server下載以下文件:

  • knife.rb Administrator > Organizations > Select your organization > Gernerate Knife Config > Save File
  • ORGANIZATION-validator.pem Administrator > Organizations > Select your organization> Reset Validation Key > Download
  • USER.pem Administrator > Users > Select your user name > Reset Key > Download
    下載後將這些文件復制到.chef文件夾
    下載證書:
    $ knife ssl fetch

    下載的證書保存在.chef/trusted_certs/目錄下。

    驗證安裝

    執行以下命令查看是否能連接到Chef Server:

    $ cd chef-repo
    $ knife ssl check

    安裝Client

    安裝Chef client

    # rpm -Uvh chef-12.18.31-1.el7.x86_64.rpm

    驗證

    $ chef-client -v

    查看幫助

    $ chef-client -h

    如果Chef Server使用了FQDN,請註意配置/etc/hosts

    Chef的使用

    第一個例子 - local-mode

    創建cookbook

    進入Workstation的chef-repo/cookbooks目錄,執行以下命令:

    $ chef generate cookbook first_cookbook

    編輯first_cookbook/recipes/default.rb文件

    內容如下:

    file "#{ENV[‘HOME‘]}/test.txt" do  
    content ‘This file was created by Chef!‘  
    end

    運行chef-client

    $ chef-client --local-mode --runlist first_cookbook

    $ chef-client --local-mode --runlist ‘recipe[first_cookbook]‘

    $ chef-client --local-mode default.rb

    以上命令以local模式(不依賴Chef Server)運行,將在home目錄下創建一個test.txt文件。刪除這個文件再次運行命令,會再次生成文件;改變文件內容再次運行命令,文件內容會恢復;改變recipe content內容再運行命令,文件內容會更新。

    增加一個goodbye.rb

    內容如下:

    file "#{ENV[‘HOME‘]}/test.txt" do  
    action :delete  
    end 

    執行如下命令刪除文件:

    $ chef-client --local-mode --runlist ‘recipe[first_cookbook::goodbye]‘

    $ chef-client --local-mode goodbye.rb

    第二個例子 - Manage Noe - 安裝Apache HTTP Server

    創建cookbook

    $ chef generate cookbook cookbooks/learn_chef_httpd

    創建home page 模板

    $ chef generate template cookbooks/learn_chef_httpd index.html

    這將在learn_chef_httpd/templates目錄下創建名為index.html.erb的文件。編輯內容如下:

    <html>  
    <body>  
    <h1>hello from <%= node[‘fqdn‘] %></h1>  
    </body>  
    </html> 

    編輯recipe deault.rb

    內容如下:

    package ‘httpd‘    
    service ‘httpd‘ do  
    action [:enable, :start]  
    end    
    template ‘/var/www/html/index.html‘ do  
    source ‘index.html.erb‘  
    end

    通常情況cookbook保存在SCM上,但也應在Chef Server保存一個副本,這樣從每一個Node都能訪問。

    上傳cookbook:

    $ knife cookbook upload learn_chef_httpd

    檢查是否上傳成功:

    $ knife cookbook list

    說明:當更新cookbook再次上傳前,請更新cookbook version(metadata.rb)

Bootstrap your node

Node的用戶或為root或有sudo權限。
使用Private key連接:

$ knife bootstrap 192.168.145.131 --ssh-user test --sudo --identity-file ~/.ssh/private_key --node-name node1-centos --run-list ‘recipe[learn_chef_httpd]‘

使用密碼連接:

$ knife bootstrap 192.168.145.131 --ssh-user test --ssh-password ‘PASSWORD‘ --sudo --use-sudo-password --node-name node1-centos --run-list ‘recipe[learn_chef_httpd]‘

執行後Node端會下載cookbook,下載證書(證書保存在/etc/chef/trusted_certs目錄下),執行run-list。

測試

檢查 Node

$ knife node list
   node1-centos

查看node信息

$ knife node show node1-centos
   Node Name:   node1-centos
   Environment: _default
   FQDN:        node1-centos
   IP:          192.168.145.131
   Run List:    recipe[learn_chef_httpd]
   Roles:      
   Recipes:     learn_chef_httpd, learn_chef_httpd::default
   Platform:    centos 7.2.1511
   Tags:

訪問apache

curl 192.168.145.131

bootstrap僅需運行一次,當更新Node時,運行如下命令:
使用Private key

$ knife ssh ‘name:node1-centos‘ ‘sudo chef-client‘ --ssh-user USER --identity-file IDENTITY_FILE --attribute ipaddress

使用密碼

$ knife ssh ‘name:node1-centos‘ ‘sudo chef-client‘ --ssh-user USER --ssh-password ‘PASSWORD‘ --attribute ipaddress

‘name:node1-centos‘可以使用通配符,如‘’name:node1-*‘,這樣所有名字以”node1-“開頭的Node都會被更新。

參考文檔

Chef Docs
Run chef-client periodically
AWS OpsWorks User Guide
Deploying a multi-node application using CloudFormation and Chef

Chef學習筆記(一)--基礎知識與安裝配置