用vagrant和Chef Solo在实机上实施。构建centos6.5 + nginx,PHP,Ruby,MySQL环境

在实际设备上验证了《Chef实践入门》第6章自动构建应用程序执行环境的备忘录。

0.环境前提
0. 环境的先决条件

已经安装了MacOSX的Vagrant和VirtualBox。

1. 安装Bundler,并安装Chef、Knife-solo和Berkshelf。

(Bundler是用于管理Gem的Ruby工具)

#環境用ディレクトリの作成
mkdir lnmpr
cd lnmpr

#Bundlerのインストール
sudo gem install bundler

#Gemfile作成
cat <<'EOF' > Gemfile
source 'https://rubygems.org'
gem 'chef'
gem 'knife-solo'
gem 'berkshelf'
EOF

#bundleコマンドの実行
bundle install

#Vagrantfile作成
vagrant init

2. 安装nginx

(1) 由knife-solo创建的烹饪书单。

 bundle exec knife cookbook create nginx -o ./site-cookbooks

(2) 创建nginx配方

 include_recipe "yum-epel"
 package "nginx" do
    action :install
 end

 service "nginx" do
    action [ :enable, :start ]
    supports :status =>true, :restart =>true, :reload =>true
 end

创建Berksfile文件,并定义运行簿的依赖关系。

*嗯,嗯 – yum-epel无法正常运行,直到从https://supermarket.getchef.com下载并安装至本地的site-cookbooks。在这里遇到了一些问题。

source "https://supermarket.getchef.com"
cookbook 'yum', path: "./site-cookbooks/yum"
cookbook 'yum-epel', path: "./site-cookbooks/yum-epel"
cookbook 'nginx', path: "./site-cookbooks/nginx"

执行berks vendor命令以下载社区烹饪书。

 bundle exec berks vendor ./cookbooks

 #yum-epel,nginx、依存関係のあるその他のcookbooksが配置されている事を確認
 ls -Rla ./cookbooks

(5)安装vagrant-omnibus插件

 vagrant plugin install vagrant-omnibus
 vagrant plugin list

(6)Vagrantfile的配置

  VAGRANTFILE_API_VERSION = "2"

  Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.hostname = "guest"
  config.vm.box = "centos6.5"
  config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5-i386_chef-provisionerless.box"

  config.vm.network "private_network", ip: "192.168.33.10"

  # vagrant-omnibusの有効化
  config.omnibus.chef_version = :latest
  # Chef solo の設定
  config.vm.provision :chef_solo do |chef|
    # クックブックの配置場所
    chef.cookbooks_path = ["./cookbooks","./site-cookbooks"]  
    #適用するクックブックの定義
    chef.run_list = %w[
      recipe[yum]
      recipe[yum-epel]
      recipe[nginx]
    ]
  end
end

(7) 虛擬伺服器的啟動與配置

vagrant up --provision

确认

从浏览器访问192.168.33.10,确认nginx界面。

Kobito.cM2ICH.png

3. 安装PHP5.5(php、php-fpm、php-opcache)

(1) 通过knife-solo创建cookbook

bundle exec knife cookbook create php-env -o ./site-cookbooks

(2) 制作食谱

 yum_repository 'remi' do
    description 'Les RPM de Remi -Repository'
    baseurl 'http://rpms.famillecollet.com/enterprise/6/remi/x86_64/'
    gpgkey 'http://rpms.famillecollet.com/RPM-GPG-KEY-remi'
    fastestmirror_enabled true
    action :create
end

yum_repository 'remi-php55' do
    description 'Les RPM de remi de PHP5.5 pour Enterprise Linux6'
    baseurl 'http://rpms.famillecollet.com/enterprise/6/php55/$basearch/'
    gpgkey 'http://rpms.famillecollet.com/RPM-GPG-KEY-remi'
    fastestmirror_enabled true
    action :create
end

%w{php php-fpm php-opcache}.each do |pkg|
    package pkg do
        action :install
        notifies :restart, "service[php-fpm]"
    end
end

service "php-fpm" do
    action [:enable, :start]
end

(3) 修改Vagrantfile

    chef.run_list = %w[
      recipe[yum-epel]
      recipe[nginx]
      #以下行を追加
      recipe[php-env]
    ]

(4)编辑Berksfile

请增加以下内容

 cookbook "php-env", path:"./site-cookbooks/php-env"

(5) 执行berks vendor命令

bundle exec berks vendor ./cookbooks

执行供应计划

vagrant provision 

(7) 确认在客户操作系统上已安装了PHP。

vagrant  ssh
yum list installed | grep php 
exit

3. 更改nginx的配置文件 (nginx与PHP-FPM协作)

创建模板

user nginx;
worker_processes 1;

error_log   /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events{
    worker_connections 1024;
}

http{
    include /etc/nginx/mime.types;
    default_type application/octes-stream;
    log_format main '$remote_addr - $remote_user [$time_local] "$request"'
        '$status $body_bytes_sent "$http_referer"'
        '"$http_user_agent" "http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log main;
    sendfile    on;
    keepalive_timeout 65;

    server{
        listen 80 default_server;
        server_name _;

        location / {
            root    /usr/share/nginx/html;
            index   index.html index.htm index.php;
        }

        _page 404   /404.html;
        location = /404.html {
            root /usr/share/nginx/html;
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page 500 502 503 504 /50x.html;
        location = /50x.html{
            root    /usr/share/nginx/html;
        }
        <% if node['nginx']['env'].include?("php") %>
        location ~ \.php$ {
            fastcgi_pass    127.0.0.1:9000;
            fastcgi_index   index.php;
            fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include     fastcgi_params; 

        }
        <% end %>
    } 

}

将nginx的配置文件nginx.conf.erb添加到nginx的recipe中以使其生效。

请增加以下内容

 template 'nginx.conf' do
    path    '/etc/nginx/nginx.conf'
    source  "nginx.conf.erb"
    owner   'root'
    group   'root'
    mode    '0644'
    notifies    :reload, "service[nginx]"
 end

(3) 设定Attribute的初始值

default['nginx']['env'] = []

(4) 在Vagrant文件中添加 provisioning 配置。

在config.vm.provision下添加以下内容。

 #Attributeの定義
    chef.json = {
      nginx: {
        env: ["php"]
      }
    }

(5)执行berks vendor命令

bundle exec berks vendor ./cookbooks

(6) 执行配置(输出日志)

VAGRANT_LOG=info vagrant provision >&vagrant.log

(7)通过浏览器进行访问确认。

请在客户端创建以下文件

<?php
phpinfo();
?>

(8) 通过浏览器连接到192.168.33.10/index.php,并进行显示确认。

Kobito.ZqJ6Oh.png

4. Ruby环境的建立

(1) 使用Knife Solo 创建 Cookbook。

bundle exec knife cookbook create ruby-env -o ./site-cookbooks

(2)编辑 Berksfile

请补充以下内容。

 cookbook "ruby-env", path:"./site-cookbooks/ruby-env"

(3) 修改Vagrantfile

    chef.run_list = %w[
      recipe[yum]
      recipe[yum-epel]
      recipe[nginx]
      recipe[php-env]
      #以下行を追加
      recipe[ruby-env]
    ]

(4) 制作食谱

创建配方(进行的步骤:安装rbenv,并使用rbenv的插件ruby-build安装ruby)


%w{gcc git openssl-devel sqlite-devel}.each do |pkg|
    package pkg do
        action :install
    end
end

git "/home/#{node['ruby-env']['user']}/.rbenv" do
    repository node["ruby-env"]["rbenv_url"]
    action :sync
    user node['ruby-env']['user']
    group node['ruby-env']['group']
end

template ".bash_profile" do
    source ".bash_profile.erb"
    path "/home/#{node['ruby-env']['user']}/.bash_profile"
    mode 0644
    owner node['ruby-env']['user']
    group node['ruby-env']['group']
    not_if "grep rbenv ~/.bash_profile", :environment => {:'HOME' => "/home/#{node['ruby-env']['user']}"}
end

directory "/home/#{node['ruby-env']['user']}/.rbenv/plugins" do
    owner node['ruby-env']['user']
    group node['ruby-env']['group']
    mode 0755
    action :create
end

git "/home/#{node['ruby-env']['user']}/.rbenv/plugins/ruby-build" do
    repository node["ruby-env"]["ruby-build_url"]
    action :sync
    user node['ruby-env']['user']
    group node['ruby-env']['group']
end

execute "rbenv install #{node['ruby-env']['version']}" do
    command "/home/#{node['ruby-env']['user']}/.rbenv/bin/rbenv install #{node['ruby-env']['version']}"
    user node['ruby-env']['user']
    group node['ruby-env']['group']
    environment 'HOME' => "/home/#{node['ruby-env']['user']}"
    not_if { File.exists?("/home/#{node['ruby-env']['user']}/.rbenv/versions/#{node['ruby-env']['version']}")}

end

(5) 设定 Attribute 的初始值

default['ruby-env']['user'] = "vagrant"
default['ruby-env']['group'] = "vagrant"
default['ruby-env']['version'] = "2.1.1"
default["ruby-env"]["rbenv_url"] = "https://github.com/sstephenson/rbenv"
default["ruby-env"]["ruby-build_url"] = "https://github.com/sstephenson/ruby-build"

使用模板来更改环境变量。

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashsrc ]; then
    . ~/.bashsrc
fi

# User specific enviroment and startup programs
PATH=$PATH:$HOME/bin
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

(7)执行berks vendor命令。

bundle exec berks vendor ./cookbooks

(8) 执行供给

VAGRANT_LOG=info vagrant provision >&vagrant.log

确认在客户操作系统中安装了 Ruby 2.1.1。

vagrant  ssh
rbenv versions
#2.1.1  と表示されればOK
exit

5. Unicorn的安装

使用Rails框架时,在AP服务器上安装Uicorn。

(1)修复ruby-env菜谱

请在以下内容中添加(Unicorn的安装)。

execute "rbenv global #{node['ruby-env']['version']}" do
    command "/home/#{node['ruby-env']['user']}/.rbenv/bin/rbenv global #{node['ruby-env']['version']}"
    user node['ruby-env']['user']
    group node['ruby-env']['group']
    environment 'HOME' => "/home/#{node['ruby-env']['user']}"
end

%w{rbenv-rehash bundler}.each do |gem|
    execute "gem install #{gem}" do command "/home/#{node['ruby-env']['user']}/.rbenv/shims/gem install #{gem}"
    user node['ruby-env']['user']
    group node['ruby-env']['group']
    environment 'HOME' => "/home/#{node['ruby-env'] ['user']}"
    not_if "/home/#{node['ruby-env']['user']}/.rbenv/   shims/gem list | grep #{gem}"
    end
end

(2) 更改nginx的默认配置(与Unicorn进行配合)

user nginx;
worker_processes 1;

error_log   /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events{
    worker_connections 1024;
}

http{
    include /etc/nginx/mime.types;
    default_type application/octes-stream;
    log_format main '$remote_addr - $remote_user [$time_local] "$request"'
        '$status $body_bytes_sent "$http_referer"'
        '"$http_user_agent" "http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log main;
    sendfile    on;
    keepalive_timeout 65;

    #以下Unicorn連携用の記述1/2
    <% if node['nginx']['env'].include?("ruby") %>
    upstream unicorn{
        server unix:/tmp/unicorn.sock;
    }
    <% end %>
    #ここまで

    server{
        listen 80 default_server;
        server_name _;

        location / {
            root    /usr/share/nginx/html;
            index   index.html index.htm index.php;
        }

        error_page 404  /404.html;
        location = /404.html {
            root /usr/share/nginx/html;
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page 500 502 503 504 /50x.html;
        location = /50x.html{
            root    /usr/share/nginx/html;
        }
        <% if node['nginx']['env'].include?("php") %>
            location ~ \.php$ {
            fastcgi_pass    127.0.0.1:9000;
            fastcgi_index   index.php;
            fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include     fastcgi_params; 
            }
        <% end %>
        #以下Unicorn連携用の記述2/2
        <% if node['nginx']['env'].include?("ruby") %>
            location /unicorn{
            rewrite ^/unicorn/(.+) /$1 break;
            proxy_pass http://unicorn/$1;
            }
        <% end %>   
        #ここまで
    } 
}

(3)使用Attribute来设置初始值。

#変更前
    chef.json = {
      nginx: {
        env: ["php"]
      }
    }
#変更後
    chef.json = {
      nginx: {
        env: ["php","ruby"]
      }
    }

执行berks vendor命令

bundle exec berks vendor ./cookbooks

(5) 执行供应

VAGRANT_LOG=info vagrant provision >&vagrant.log

(6) 为了确认动作,创建一个RubyOnRails的项目

创建一个用于简单操作验证的Rails项目。

vagrant ssh
yum -y install libxml2 libxslt libxml2-devel libxslt-devel
gem install nokogiri -- --use-system-libraries
gem install rails -V
rails new test_unicorn --skip-bundle
cd test_unicorn
mkdir -p shared/{pids,log}

在客户端修改Gemfile,然后执行bundle install。

source 'https://rubygems.org'

gem 'rails', '4.0.4'
gem 'sqlite3'
gem 'sass-rails','~>4.0.2'
gem 'uglifier', '>=1.3.0'
gem 'coffee-rails','~>4.0.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder','~>1.2'

group :doc do
    gem 'sdoc',require: false
end

gem 'unicorn'

安装依赖包

(7) 创建Unicorn的配置文件。

在客户端创建Unicorn配置文件。

listen "/tmp/unicorn.sock"
worker_processes 2 # this should be >= nr_cpus
pid "/home/vagrant/test_unicorn/shared/pids/unicorn.pid"
stderr_path "/home/vagrant/test_unicorn/shared/log/unicorn.log"
stdout_path "/home/vagrant/test_unicorn/shared/log/unicorn.log"

(8) 安装Node.js

创作一本食谱手册。

bundle exec knife cookbook create nodejs -o ./site-cookbooks

②修改Berksfile文件

请添加以下内容。

cookbook "nodejs",path:"./site-cookbooks/nodejs"

创建一个用于安装Node.js的烹饪书。

%w{gcc-c++}.each do |pkg|
    package pkg do
        action :install
    end
end
remote_file "tmp/#{node['nodejs']['filename']}" do
     source "#{node['nodejs']['remote_uri']}"
end

bash "install nodejs" do
    user "root"
    cwd "/tmp"
    code <<-EOC
        tar xvzf #{node['nodejs']['filename']}
        cd #{node['nodejs']['dirname']}
        make
        make install
    EOC
end

设定属性的初始值。

default['nodejs']['version'] = "v0.10.26"
default['nodejs']['dirname'] = "node-#{default['nodejs']['version']}"
default['nodejs']['filename'] = "#{default['nodejs']['dirname']}.tar.gz"
default['nodejs']['remote_uri'] = "http://nodejs.org/dist/#{default['nodejs']['version']}/#{default['nodejs']['filename']}"

将Vagrantfile的运行列表中添加

以下增加

recipe[nodejs]

执行berks vendor命令

bundle exec berks vendor ./cookbooks

进行供应

VAGRANT_LOG=info vagrant provision >&vagrant.log

(9) 确认独角兽的动作

一只独角兽开始运行。

vagrant ssh
cd test_unicorn
bundle exec unicorn -c config/unicorn.rb -D

使用浏览器访问 http://192.168.33.10/unicorn → 错误!!已发现nginx的上游出现错误,但无法解决。放弃故障排除,暂时搁置…

将问题留给作业,继续前进。

 [error] 22931#0: *28 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.33.1, server: _, request: "GET /unicorn HTTP/1.1", upstream: "http://unix:/tmp/unicorn.sock:/", host: "192.168.33.10"

6. MySQL的安装

(1) 由knife-solo创建的烹饪书籍制作

bundle exec knife cookbook create mysql -o ./site-cookbooks

(2)将其添加到Berksfile中

cookbook "mysql" , path:"./site-cookbooks/mysql"

使用属性进行初始值设定。

default['mysql']['user'] = "vagrant"
default['mysql']['group'] =  "vagrant"
default['mysql']['server_root_password'] = "" 

(4)创建MySQL安装配方

あとで

(5) 编辑Vagrantfile


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.hostname = "guest"
  config.vm.box = "centos6.5"
  config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5-i386_chef-provisionerless.box"

  config.vm.network "private_network", ip: "192.168.33.10"

  # vagrant-omnibusの有効化
  config.omnibus.chef_version = :latest
  # Chef solo の設定
  config.vm.provision :chef_solo do |chef|
    # クックブックの配置場所
    chef.cookbooks_path = ["./cookbooks","./site-cookbooks"]

    # Attributeの定義
    chef.json = {
    #適当なパスワードに変えること
      mysql: {
        server_root_password: 'rootpass'
      },
      nginx: {
        env: ["php","ruby"]
      }
    }

    #適用するクックブックの定義
    chef.run_list = %w[
      recipe[yum]
      recipe[yum-epel]
      recipe[nginx]
      recipe[php-env]
      recipe[ruby-env]
      recipe[nodejs]
      recipe[mysql]
    ]
  end
end

(6)创建MySQL配置文件

[mysqld]
log-bin
datadir=/var/lib/mysql/mysql.sock
user=mysql

#Disebling symbolic-links is recommended to prevent assorted security risks
sybolic-links=0

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

(7) 执行berks vendor命令

bundle exec berks vendor ./cookbooks

(8) 进行设置

VAGRANT_LOG=info vagrant provision >&vagrant.log

确认:使用mysql进行连接。

vagrant ssh 
mysql -u root -p
show databases;

7. 将代码提交至 GitHub。

为了将来作为开发环境使用,我们将本次创建的cookbook等提交到GitHub。

GitHub->
GitHub->

广告
将在 10 秒后关闭
bannerAds