Usually Chef consists of three parts: workstation, Chef Server, and Chef Node.
Workstation is a machine for daily work. It needs to install the Chef Development Kit to write cookbooks and manage Chef Server and Node.
Chef Server is a central repository that stores cookbooks and the Node information it manages.
Node is a machine managed by Chef Server, that is, a machine that configures and deploys applications through Chef, and needs to install chef-client Agent.
Chef Terminology
A directory on the chef-repo workstation to store Cookbooks, Roles, Data bags, Environments, etc. The following command can be executed to create its directory structure:
$ chef generate repo REPO_NAME
Cookbooks A cookbook is the fundamental unit of configuration and policy distribution. Contains recipes, attributes, files, templates, libraries, custom resources, etc., a unit of code that defines a series of resources, configuration. Execute the following command to create a cookbook:
$ chef generate cookbook cookbooks/learn_chef
The most basic configuration element of recipes, located in the recipes directory of the cookbook, is used to define the resources of Node. It can call other resources defined in the cookbook, and can also depend on other recipes.
Attributes Node attributes, there are 6 types: default, force_default, normal, override, force_override, automatic; can be defined in 5 locations: Nodes (the ohai tool is included when installing chef-client, which is responsible for collecting attributes, called automatic attributes, For example, ipaddress, hostname, fqdn), Attribute files, Recipes, Environments, Roles, only two types of default and override are allowed in Roles and Environments. This combination produces 15 priorities (1+5+5+2+2 ), please refer to the official document Attribute Precedence for details .
An example of a properties file:
default['apache']['dir'] = '/etc/apache2' default['apache']['listen_ports'] = [ '80','443' ]
Note: default is an attribute type, node object is a hash table, and attribute names can be nested arbitrarily.
The above example implicitly uses the node object (node), which can also be added when defining:
node.default['apache']['dir'] = '/etc/apache2' node.default['apache']['listen_ports'] = [ '80','443' ]
The defined attributes can be referenced in templates, recipes, etc.
Files file resource, there are three file types:
- The cookbook_file source file is in the files directory of the cookbook, and it is deployed to the specified location of 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
- file has no source file, but directly defines the content of the 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
- remote_file deploys a remote file to 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 A special type of file -- Embedded Ruby (ERB) template, which can contain Ruby expressions and statements. The Template file should be placed in the templates directory of the cookbook, usually using the name of the target file plus .erb.
Take a look at a template - sudoers.erb, which references the automatic attribute - fqdn and uses the variables 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 -%>
Call the template in the recipe and reference the properties to assign values to the variables:
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
Properties file attributes/default.rb:
default['authorization']['sudo']['groups'] = [ 'sysadmin', 'wheel', 'admin' ] default['authorization']['sudo']['users'] = [ 'jerry', 'greg']
Library is located in the /libraries directory of the cookbook, and can use any Ruby code to create custom classes or modules, connect to databases, etc.
Resources Chef has built-in support resources, the most used part of the recipe, you can install packages , configure services , access directory , file system, create groups and users , run commands ( execute ), execute ruby code, etc.
Custom Resources can extend Chef to add your own resources, such as managing a website. The definition file is located in the resources directory of the cookbook.
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 is a global variable stored in Json format, located in the data_bags directory of chef-repo.
Create the Data Bags folder admins:
$ knife data bag create admins
Create data bag item "charlie.json":
$ knife data bag create admins charlie
The content is as follows:
{ "id": "charlie", "uid": 1005, "gid": "ops", "shell": "/bin/zsh", "comment": "Crazy Charlie" }It can be called in the recipe:
charlie = search(:admins, "id:charlie").first
Roles define service types, such as "web server", "database server", and can set run-list, attributes, etc. uniformly. Role definitions support two formats, Ruby and JSON, and are located in the roles directory of chef-repo.
{ "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": [] } }
Set Node's run-list:
$ knife node run_list set node1-centos "role[web]"
Environments Initially each organization had an environment called _default, which could not be modified or deleted. In practical applications, environments such as production, testing, and development may be created to meet different needs. The Environment definition supports both Ruby and Json formats and is located in the environments directory of chef-repo.
The following example sets the default_attributes for the dev environment:
name 'dev' description 'The development environment' cookbook_versions 'couchdb' => '= 11.0.0' default_attributes 'apache2' => { 'listen_ports' => [ '80', '443' ] }
Chef Tool
Knife 's most commonly used command-line tool for managing chef-repo and Chef Server. Many commands provided by Chef itself also call Knife.
Kitchen Cookbooks Test Tool
Berkshelf Cookbooks Dependency Management Tool
ChefSpec resources and recipes testing tool
Ohai 's tool for detecting Node properties
Having said so much, I quickly rolled up my sleeves and installed the environment. First, go to the official website https://downloads.chef.io/ to download the Chef Client, Chef Server, and Chef DK installation packages. The operating system I use is CentOS7, and the installation packages are all rpm.
Install Chef Server
prerequisites
- In order for Chef Server to be able to send emails, you need to configure the email agent
- Chef Server uses RabbitMQ, which conflicts with Apache Qpid, so Apache Qpid needs to be disabled
Configure Hostname
The hostname of Chef server must use FQDN (fully qualified domain name) or IP address. In a production environment, the FQDN should be resolvable by DNS, and in a test environment, the hostname can be added to the /etc/hosts file. If the hostname is not configured, even if the default localhost is used, only the local machine can access it normally.
# hostname 'mychefserver.example.com'
# echo "mychefserver.example.com" | tee /etc/hostname
# echo -e "127.0.0.2 `hostname` `hostname -s`" | tee -a /etc/hosts
Install Chef Server and Management Console
Management Console is Chef Server's web management console (free within 25 Nodes).
# 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
Run chef-server-ctl install directly to see other supported server-side plugins.
Description: Execute chef-server-ctl help to view commands supported by chef-server-ctl, and execute chef-server-ctl <command> -h to view command syntax and parameters.
Certificate
Chef Server enables SSL verification by default for all requests. A self-signed certificate is automatically generated when Chef Server is installed. The certificate and private key are located in the /var/opt/opscode/nginx/ca directory with the names FQDN.crt and FQDN.key.
Chef Server can also use an existing certificate. Edit the /etc/opscode/chef-server.rb file and add the following to specify the location of the certificate:
nginx['ssl_certificate'] = "/etc/pki/tls/certs/your-host.crt" nginx['ssl_certificate_key'] = "/etc/pki/tls/private/your-host.key"
Then execute:
# chef-server-ctl reconfigure
To be safe, the certificate should be updated regularly, and the chef server should be stopped first:
# chef-server-ctl stop
Then delete the original certificates $FQDN.crt and $FQDN.key. If a custom certificate is used, please use the same tool to regenerate it. Then run:
# chef-server-ctl reconfigure
# chef-server-ctl start
Verify installation
Execute the following commands:
# chef-server-ctl test
create user
The command format is as follows:
# chef-server-ctl user-create USER_NAME FIRST_NAME LAST_NAME EMAIL 'PASSWORD' --filename FILE_NAME
After the command is executed, the user's private key will be automatically generated. Specify the --filename option to save the private key to a file, otherwise it will be output to the screen.
Example:
# chef-server-ctl user-create stevedanno Steve Danno [email protected] 'abc123' --filename /path/to/stevedanno.pem
Create an organization
The command format is as follows:
# chef-server-ctl org-create short_name 'full_organization_name' --association_user user_name --filename ORGANIZATION-validator.pem
Where short_name cannot contain uppercase letters, --association_user specifies the administrator user of the organization. After the command is executed, the private key of the organization is automatically generated, and --filename defines the key storage location.
Example:
# chef-server-ctl org-create 4thcoffee 'Fourth Coffee, Inc.' --association_user stevedanno --filename /path/to/4thcoffee-validator.pem
If the option --association_user is not specified when creating an organization, you can execute the following commands to associate users, you can add multiple users to the organization, and add the -a option to set it as an administrator
# chef-server-ctl org-user-add 4thcoffee jason -a
Access Management Console using FQDN or IP, for example: https://mychefserver.example.com or https://192.168.1.10.
Install Workstation
The Chef development kit contains chef-client, Ruby, and tools like Kitchen, Berkshelf, ChefSpec.
Install Chef DK
# rpm -Uvh chefdk-1.2.22-1.el7.x86_64.rpm
installation check
$ chef verify
Output this result: Verification of component '....' succeeded
View help
$ chief -h
Placement Ruby
See where Ruby is installed
$ which ruby
To use Chef DK's embedded Ruby, execute the following command to add the Chef DK path to the environment variable PATH:
$ echo 'eval "$(chef shell-init bash)"' >> ~/.bash_profile
Configure chef-repo
Create chef-repo
$ chef generate repo chef-repo
Create the .chef directory
$ mkdir chef-repo/.chef
Because Workstation wants to interact with Server, you need to log in to Server to download the following files:
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
Copy these files to the .chef folder after downloading
Download the certificate:
$ knife ssl fetch
The downloaded certificate is saved in the .chef/trusted_certs/ directory.
Verify installation
Execute the following command to see if you can connect to Chef Server:
$ cd chef-repo
$ knife ssl check
Install Client
Install Chef client:
# rpm -Uvh chef-12.18.31-1.el7.x86_64.rpm
verify
$ chef-client -v
View help
$ chief-customer -h
If Chef Server uses FQDN, please configure /etc/hosts
Use of Chef
First example - local-mode
Go to the chef-repo/cookbooks directory of Workstation and execute the following command to create a cookbook:
$ chef generate cookbook first_cookbook
Edit the first_cookbook/recipes/default.rb file as follows:
file "#{ENV['HOME']}/test.txt" do content 'This file was created by Chef!' end
Run chef-client:
$ chef-client --local-mode --runlist first_cookbook
or
$ chef-client --local-mode --runlist 'recipe[first_cookbook]'
or
$ chef-client --local-mode default.rb
The above command is run in local mode (without relying on Chef Server) and will create a test.txt file in the home directory. Delete this file and run the command again, the file will be generated again; change the content of the file and run the command again, the content of the file will be restored; change the content of the recipe content and run the command, the content of the file will be updated.
Add another goodbye.rb with the following content:
file "#{ENV['HOME']}/test.txt" do action :delete end
Execute the following command to delete the file:
$ chef-client --local-mode --runlist 'recipe[first_cookbook::goodbye]'
or
$ chef-client --local-mode goodbye.rb
Second Example - Manage Noe - Install Apache HTTP Server
Create a cookbook:
$ chef generate cookbook cookbooks/learn_chef_httpd
Create the home page template:
$ chef generate template cookbooks/learn_chef_httpd index.html
This will create a file named index.html.erb in the learn_chef_httpd/templates directory. Edited as follows:
<html> <body> <h1>hello from <%= node['fqdn'] %></h1> </body> </html>
Edit recipe deault.rb, the content is as follows:
package 'httpd' service 'httpd' do action [:enable, :start] end template '/var/www/html/index.html' do source 'index.html.erb' end
Usually the cookbook is kept on the SCM, but a copy should also be kept on the Chef Server so that it can be accessed from every Node.
Run the following command to upload the cookbook:
$ knife cookbook upload learn_chef_httpd
Check if the upload was successful:
$ knife cookbook list
Note: Please update the cookbook version (metadata.rb) when updating the cookbook before uploading again
Bootstrap your node
The Node user is either root or has sudo privileges.
Connect using 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]'
To connect with a password:
$ 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]'
After execution, the Node side will download the cookbook, download the certificate (the certificate is stored in the /etc/chef/trusted_certs directory), and execute run-list.
test:
Check Node
$ knife node list
node1-centos
View node information
$ 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:
access apache
curl 192.168.145.131
bootstrap only needs to be run once, when updating Node, run the following command:
Use private key
$ knife ssh 'name:node1-centos' 'sudo chef-client' --ssh-user USER --identity-file IDENTITY_FILE --attribute ipaddress
use password
$ knife ssh 'name:node1-centos' 'sudo chef-client' --ssh-user USER --ssh-password 'PASSWORD' --attribute ipaddress
'name:node1-centos' can use wildcard characters, such as ''name:node1-*', so that all Nodes whose names start with "node1-" will be updated.
Deploying a multi-node application using CloudFormation and Chef