Đơn giản hóa việc cài đặt môi trường với Chef
Bài đăng này đã không được cập nhật trong 6 năm
Một công việc quen thuộc với các developer khi phát triển một dự án web là cài đặt môi trường phát triển. Khi join dự án, ban đầu dev sẽ nhận đc một danh sách các công nghệ sẽ sử dụng để dự án có thể vận hành trên môi trường production. Và tất nhiên dev cần tái hiện gần giống nhất môi trường production dưới local của mình, để tránh phát sinh trường hợp "ơ dưới máy em vẫn chạy bình thường mà" với new dev.
Có nhiều cách khác nhau cho dev lựa chọn để thực hiện việc cài đặt này.
- Cách 1: bằng "tay". Đại loại là chúng ta sẽ ngồi gõ “sudo apt-get install package-abc package-xyz….”. Với những dự án mà việc cài đặt đơn giản thì thực hiện cách này cũng không có vấn đề gì lắm. Nhưng với những dự án mà tài liệu hướng dẫn cài đặt môi trường dài đến vài trang A4 thì đọc và làm theo nó step by step thật là ngán ngẩm và dễ phát sinh lỗi trong quá trình cài đặt (facepalm)
- Cách 2: sử dụng shell script. Là một bước nâng cấp so với cách 1. Việc cài đặt đã có thể thực hiện một cách tự động ở mức nào đó và có thể chia sẻ file cài đặt này giữa nhiều máy để tiết kiệm công sức. Tuy nhiên ta vẫn khó quản lý các thành phần cần cài đặt. Và shell script cũng là một trong những môn khoai nhất hồi còn là sinh viên, ít nhất là với đa số mọi người.
- Cách 3: sử dụng một công cụ quản lí các thiết lập cho server. Là một bước nâng cấp của cách 2 khi việc cài đặt có thể thực hiện tự động giữa nhiều máy và việc quản lý cũng dễ dàng.
Chúng ta sẽ đi tìm hiểu một công cụ quản lí các thiết lập cho server là Chef. Như đã nói ở trên Chef là một công cụ quản lý giúp cho việc config một hay nhiều server được thực hiện tự động và dễ dàng. Nhờ đó developer có thể giành thời gian và tâm trí cho việc phát triển sản phẩm của mình.
Các khái niệm trong chef
- Chef Client: command line tool, để thực hiện các thao tác config server
- Chef Solo: một phiên bản của Chef Client cho phép config server mà không phụ thuộc vào bất kỳ server nào khác.
- Node: host chạy Chef Client, đó có thể là web server, database server...
- Recipes: các file Ruby chứa các câu lệnh chạy trên node để thực thi các tác vụ cài đặt hay cấu hình một service (nginx, apache, mysql...)
- Cookbook: tập hợp các Recipes phục vụ cho một chức năng lớn nào đó. Mỗi recipe chỉ nên thực hiện một chức năng đơn giản, sau đó các recipe đơn giản này được tập hợp trong một cookbook để thực hiện đầy đủ một chức năng phức tạp hơn.
- Template: là 1 file erb chứa các nội dung soạn sẵn cho các file config, html...trong đó ta có thể nhúng code ruby để linh hoạt trong việc sử dụng và tùy biến nội dung. Thường được sử dụng để tạo file config cho các service.
- Attribute: định nghĩa các biến được truyền trong Chef và có thể sử dụng ở recipes, templates.
- Resources: là nơi chứa đựng các resource của các node bao gồm files, directories, users và services.
- Role: gồm các file config có thể tái sử dụng ở nhiều node
Ưu điểm của Chef?
- Ruby dễ đọc hơn rất nhiều so với shell script, hơn nữa nhiều dev lại biết sẵn ruby rồi. Và nếu bạn sử dụng Chef với vagrant, thì chỉ cần học ruby bạn sẽ viết được cả Chef và Vagrantfile, một công đôi việc.
- Có rất nhiều cookbook được chia sẻ trên supermarket của chef và cả các nguồn khác nữa. Như các công thức nấu ăn hay bản thiết kế in 3D vậy, bạn chỉ việc kéo chúng về và sử dụng chứ không cần xây dựng từ đầu. Thêm nữa những cookbook chất lượng cao được viết bởi các cao thủ sẽ được cộng đồng đánh giá cao với lượt tải lớn, do đó bạn dễ dàng tìm thấy chúng.
- Có thể thay thế cho tài liệu hệ thống. Với những đoạn code ruby rất clear và rành mạch thì những tài liệu hệ thống có thể không cần đến nữa
- Có khả năng làm việc với các hệ điều hành khác nhau một cách dễ dàng. Với Chef chúng ta dễ dàng detect các hệ điều hành khác nhau để đưa ra các hành động phù hợp. Ví dụ cùng một package nhưng mỗi OS sử dụng một lệnh khác nhau để cài đặt
case node['platform_family']
when 'rhel', 'fedora'
#some code here
when 'debian'
#some code here
end
- Chef vừa có khả năng quản lý thiết lập cho 1 máy cũng như quản lý cho cả 1 hệ thống server của công ty
- Chef có thể tích hợp trong các platform điện toán đám mây phổ biến gồm Rackspace, Internap, Amazon EC2, Google Cloud Platform, OpenStack, SoftLayer, and Microsoft Azure để có thể tự động config nhiều server cùng lúc. Điều này rất hữu ích vì hiện nay nhu cầu sử dụng các platform này ngày càng tăng cao.
Cài đặt
Do code Chef sử dụng ngôn ngữ Ruby nên việc đầu tiên là ta cần cài Ruby cho máy cần chạy Chef. Dao sắc không gọt được chuôi. Việc cài đặt Ruby đành phải thực hiện bằng tay, shell script hoặc một công cụ quản lí các thiết lập cho server thôi (yaoming). Sau khi cài ruby bạn cài 2 gem knife-solo và librarian-chef để có thể bắt đầu thao tác với Chef. Nếu muốn thực hiện các thao tác nâng cao thì bạn có thể download và cài đặt Chefdk từ https://downloads.chef.io/chefdk. Chefdk bao gồm chef-client, an embedded version of Ruby, RubyGems, OpenSSL, key-value stores,... nói chung là tất cả những gì bạn cần có để làm việc với Chef.
yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison iconv-devel sqlite-devel
curl -sSL https://rvm.io/mpapis.asc | gpg --import -
curl -L get.rvm.io | bash -s stable
source /etc/profile.d/rvm.sh
rvm reload
rvm requirements run
rvm install 2.1
gem install bundler
cat <<EOF >Gemfile
source "https://rubygems.org"
gem 'knife-solo'
gem 'librarian-chef'
EOF
bundle install
Sau đây mình sẽ giới thiệu 3 thao tác cơ bản và đơn giản nhất khi sử dụng Chef để cài đặt môi trường. Xin nhắc lại Chef là một công cụ cực kỳ mạnh và đây chỉ là 3 trong số rất nhiều các thao tác ta có thể thực hiện với Chef mà thôi. Nhưng như thế cũng là tạm đủ để công việc cài đặt của chúng ta đc thoải mái và chính xác hơn rất nhiều.
Khởi tạo thư mục làm việc với tên chef-repo-demo:
mkdir ~/chef-repo-demo
cd ~/chef-repo-demo
Làm việc với file
Đây là thao tác đơn giản nhất để tìm hiểu về Chef. Bạn sẽ cần dùng đến nó khi tạo file config của apache hoặc nginx chẳng hạn. Ví dụ kinh điển là sử dụng Chef tạo một file helloworld.txt với nội dung "hello world".
Tạo file hello.rb như sau:
file 'helloworld.txt' do
content 'hello world'
end
Rồi sử dụng lệnh chef-apply file_name
để thực thi code Chef vừa viết:
chef-apply hello.rb
Output nhận được như sau:
Recipe: (chef-apply cookbook)::(chef-apply recipe)
* file[helloworld.txt] action create
- create new file helloworld.txt
- update content in file helloworld.txt from none to b94d27
--- helloworld.txt 2018-05-27 15:02:39.766562300 +0000
+++ ./.chef-helloworld.txt20180527-246-189odei 2018-05-27 15:02:39.764699300 +0000
@@ -1 +1,2 @@
+hello world
Một điều quan trọng là, nếu nội dung phần 'content' ở trên không thay đổi, hoặc đã tồn tại một file helloworld.txt với nội dung như vậy thì khi chạy lệnh trên ta sẽ nhận được output thông báo mọi thứ đã update và không có action nào được thực thi. May mắn là điều trên cũng được áp dụng với các tài nguyên như package và service. Nếu ta thực hiện install một package hay service với version đã tồn tại trong hệ thống thì hành động này sẽ được bỏ qua giúp tiết kiệm thời gian và tài nguyên.
Đây là cấu trúc đầy đủ của một block file trong Chef (bạn có thể tham khảo kỹ hơn tại https://docs.chef.io/resource_file.html)
file 'name' do
atomic_update True, False
backup False, Integer
checksum String
content String
force_unlink True, False
group String, Integer
inherits True, False
manage_symlink_source True, False
mode String, Integer
notifies # see description
owner String, Integer
path String # defaults to 'name' if not specified
rights Hash
sensitive True, False
subscribes # see description
verify String, Block
action Symbol # defaults to :create if not specified
end
Làm việc với package và service
Điều không thể thiếu khi cài đặt môi trường là cài đặt package và service. Nginx, httpd, php, nodejs, npm, yarn, git, open ssl...là những package và service thường xuyên được sử dụng trong các web server. Với Chef ta có thể cài đặt và quản lý nhiều service một cách đơn giản và rành mạch. Cú pháp để cài đặt và khởi động nginx như sau:
########## install nginx ##########
['epel-release', 'nginx'].each do |p|
package p do
action :install
end
end
########## start nginx ##########
service 'nginx' do
action [:enable, :start]
end
Cấu trúc đầy đủ của một block pakage như sau:
package 'name' do
allow_downgrade True, False # Yum, RPM packages only
arch String, Array # Yum packages only
default_release String # Apt packages only
flush_cache Array
gem_binary String
homebrew_user String, Integer # Homebrew packages only
notifies # see description
options String
package_name String, Array # defaults to 'name' if not specified
response_file String # Apt packages only
response_file_variables Hash # Apt packages only
source String
subscribes # see description
timeout String, Integer
version String, Array
action Symbol # defaults to :install if not specified
end
Cú pháp đầy đủ cho tất cả thuộc tính của resouce service:
init_command String
notifies # see description
options Array, String
pattern String
priority Integer, String, Hash
reload_command String
restart_command String
service_name String # defaults to 'name' if not specified
start_command String
status_command String
stop_command String
subscribes # see description
supports Hash
timeout Integer # Microsoft Windows only
action Symbol # defaults to :nothing if not specified
end
Làm việc với command
Một thao tác khác cũng khá thường xuyên được sử dụng đó là thực thi các command. Bởi vì không phải service nào cũng có thể cài đặt đơn giản thông qua các trình quản lý package mà chúng ta phải download về từ đâu đó rồi thực hiện. Và nhiều thao tác khác nữa cần thực thi bằng command.
Ví dụ cài đặt php composer:
execute 'download composer' do
command 'curl -sS https://getcomposer.org/installer | php'
not_if { File.exist?('/usr/local/bin/composer') || File.exist?('composer.phar') }
end
execute 'move to /usr/local/bin/' do
command 'mv -f composer.phar /usr/local/bin/composer'
not_if { File.exist?('/usr/local/bin/composer' || !File.exist?('composer.phar')) }
end
Đây là cấu trúc đầy đủ của một block thực thi command trong Chef:
execute 'name' do
command String, Array # defaults to 'name' if not specified
creates String
cwd String
environment Hash # env is an alias for environment
group String, Integer
live_stream True, False
notifies # see description
returns Integer, Array
sensitive True, False
subscribes # see description
timeout Integer, Float
umask String, Integer
user String
password String
domain String
action Symbol # defaults to :run if not specified
end
Đến đây ta đã có thể sử dụng Chef để cài đc rất nhiều các service và package phổ biến như nginx, apache, php, nodejs, mysql,... Sau đây là code đầy đủ để có thể cài đặt php7.1 và composer lên server Centos:
########################## install php
execute 'epel-release-latest-7' do
command 'rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm'
not_if 'rpm -qa | grep epel-release-7-[0-9]*.noarch'
end
execute 'install webtatic-release' do
command 'rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm'
not_if 'rpm -qa | grep webtatic-release*.'
end
%w(php71w-cli php71w-common php71w-curl php71w-json php71w-mbstring php71w-mcrypt php71w-mysql php71w-fpm php71w-pdo php71w-gd php71w-xml php71w-zip).each do |p|
package p do
action :install
end
end
### start php-fpm
service 'php-fpm' do
action [:enable, :start]
end
########################## install composer
execute 'download composer' do
command 'curl -sS https://getcomposer.org/installer | php'
not_if { File.exist?('/usr/local/bin/composer') || File.exist?('composer.phar') }
end
execute 'move to /usr/local/bin/' do
command 'mv -f composer.phar /usr/local/bin/composer'
not_if { File.exist?('/usr/local/bin/composer' || !File.exist?('composer.phar')) }
end
Ở bài viết sau ta sẽ tiếp tục tìm hiều các khái niệm cơ bản khác để sử dụng được Chef trong nhiều trường hợp hơn, đó là Cookbook, recipe và template.
Tham khảo:
https://viblo.asia/p/huong-dan-su-dung-chef-al5XRBd3GqPe
https://viblo.asia/p/tim-hieu-vagrant-phan-2-vagrant-chef-wznVGLqQvZOe
All rights reserved