01d. さくらのクラウド環境構築(CentOS7+Ansible)(備忘録)

さくらのクラウドLAMP環境構築及びWordPressのテーマ及びプラグインのインストールまでをおこなっていきます。ワークショップ用なので、時間を省略する為にもrootユーザのまま実施していきます。

Ansibleの概要は下記を参照
01c. 開発環境構築(Windows 10+Ubuntu18.04+Ansible)(備忘録)

さくらのクラウド

コントロールパネルにログイン

ワークショップ当日は会場先でさくらのクラウドを提供して頂けるのですが、準備を兼ねて自分でも使用してみました。アカウント開設後、コントロールパネルログインします。


 

サーバの追加

石狩第2ゾーンを選択し(近い東京第1ゾーンは少し割高なので)、サーバを選択し追加

今回はディスクイメージはCentOS7.6を選択しました。

最小構成プランを選択

公開鍵なしを選択(後で作成)

ホスト名作成数を入力
1ホスト(1GB)/月あたり2000円程度(データ転送料不要/SSD20GB)
同スペックのAWS EC2は1500円程度(データ転送料込み/HDD8GB)
検証で2-3日使用したい時は、さくらのクラウドを利用するのもありかなと思います。
※ 2017年3月よりサーバー停止中の利用料金が無料化されました(ディスク料金別)

作成ボタンをクリック

サーバが作成されます。

暫くすると、サーバが起動されます。

※ ansible-02は、web-01に変更しました。

SSH公開鍵認証

ansible-01上で作業していきます。

# vi /etc/hosts											# Webサーバをhostsファイルに追加
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

# Webサーバ
153.XX.XX.XX	web-01
153.XX.XX.XX	web-02
 :


# ssh-keygen -t ecdsa								# 楕円曲線暗号を用いた方式(RSAよりも解読が困難)
Generating public/private ecdsa key pair.
Enter file in which to save the key (/root/.ssh/id_ecdsa):
Enter passphrase (empty for no passphrase):						# パスフレーズは今回無し
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_ecdsa.		# 秘密鍵
Your public key has been saved in /root/.ssh/id_ecdsa.pub.		# 公開鍵
  :

# ls -l .ssh													# 公開鍵と秘密鍵が作成されていることを確認
-rw------- 1 root root 227  6月  2 20:29 id_ecdsa
-rw-r--r-- 1 root root 177  6月  2 20:29 id_ecdsa.pub

# ssh-copy-id web-01											# 公開鍵の転送
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_ecdsa.pub"
  :
root@web-01's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'web-01'"
and check to make sure that only the key(s) you wanted were added.

# ssh web-01					# パスワード無しでログインできることを確認
# hostname						# 該当ホストにログインできたことを確認
web-01
# cat .ssh/authorized_keys		# 公開鍵が転送されていることを確認
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCbobnxvHLTER7LaJWfaZD1tsq7zlC+jsuKBSga7HY96Z6pkMcz+qZTDsX76H1UfC95qvEfvmhb1iFwCECpC3YQ= root@ansible-01
# exit

Ansibleのインストール

# yum update					# インストール済みのパッケージをアップデート
# yum install epel-release		# EPELリポジトリのインストール(アドオンパッケージ群:Ansibleのインストールで必要)
# yum repolist -q				# epelリポジトリが有効になっていることを確認
リポジトリー ID                           リポジトリー名                                                                   状態
base/7/x86_64                             CentOS-7 - Base                                                                  10,019
elrepo                                    ELRepo.org Community Enterprise Linux Repository - el7                              122
epel/x86_64                               Extra Packages for Enterprise Linux 7 - x86_64                                   13,195
extras/7/x86_64                           CentOS-7 - Extras                                                                   413
updates/7/x86_64                          CentOS-7 - Updates                                                                1,945

# python --version				# python3がインストールされている場合は、ansibleが対応しているか確認が必要
Python 2.7.5

# yum install ansible			# Ansibleのインストール
# ansible --version
ansible 2.8.0

# ansible localhost -m ping -o
localhost | SUCCESS => {"changed": false, "ping": "pong"}	# pingモジュールがpongと応答を返すことを確認

# ansible web-01 -m ping -o		# 下記インベントリファイルをまだ作成していないので、WARNINGが出力される
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: web-01

 

インベントリファイル作成

$ vi /etc/ansible/hosts						# 最下行に以下のように追記
  :
[localhost]
127.0.0.1

[web]
web-01
web-02
 :

# ansible web-01 -m ping -o					# WARNING出力が無くなったことを確認
web-01 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}

vimが苦手な人は、ドットインストールで学習できます。
vim入門 (全18回:無料)
 

クレデンシャル

下記のようにユーザ認証情報を付与することもできます。

# ansible web-01 -m ping -o -u root -k
SSH password:						# パスワードを入力

簡単なPlaybookの作成

・Playbookのサンプル

# vi sample_playbook.yml							# Playbookの作成
- hosts: web-01
  vars:
    sample_vars: "Hello Ansible!!"
  tasks:
    - shell: uptime
      register: result								# モジュールの実行結果を変数に保存

    - debug:
        msg: "{{ result.stdout }}"					# 標準出力を表示

    - debug:
        msg: "{{ sample_vars }}"

・実行結果

# --ask-become-passを付与することで、sudo実行の際のパスワードを入力できる(今回は特に不要)
# ansible-playbook sample_playbook.yml --ask-become-pass	# Playbookの実行
BECOME password:											# sudo実行の際のパスワードを入力

PLAY [web-01] *******************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************
ok: [web-01]

TASK  ********************************************************************************************************************
changed: [web-01]

TASK [debug] ********************************************************************************************************************
ok: [web-01] => {
    "msg": " 16:32:11 up  2:37,  2 users,  load average: 0.00, 0.01, 0.05"
}

TASK [debug] ********************************************************************************************************************
ok: [web-01] => {
    "msg": "Hello Ansible!!"
}

PLAY RECAP **********************************************************************************************************************
web-01                     : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

LAMP環境を構築するPlaybook作成&実行(ansibleサーバ上)

事前準備

テンプレートとして配布するファイルを事前作成する

# vi phpinfo.php
# 先頭行が"< ?php"と表示されてしまっていますが、正しくは"<?php"です
< ?php
phpinfo();
?>

# vi my.cnf.j2
[client]
user=root
password=wpadmin

 

LAMP環境用Playbook作成

# vi web-01_lamp_playbook.yml
- name: LAMP環境構築(さくらのクラウド)
  hosts: "{{ hostname }}"
  #become: true                                 # 今回はrootユーザで実行するのでsudo不要
  vars:
    hostname: web-01                            # hostname変数を設定
    database_name: wp
    db_username: wpadmin
    db_password: wpadmin
  tasks:
    #- name: 'yum update'                       # 時間が掛かるので今回のワークショップでは省略
    #  yum:
    #    name: '*'
    #    state: latest                          # パッケージを最新の状態に更新

    - name: PHPインストール
      yum:
        name: ['epel-release-7-11', 'php-5.4.16', 'php-mbstring-5.4.16']
        state: present                          # パッケージがインストールされていなければインストール
        # epel-release: 拡張パッケージリポジトリ
        # php-mbstring: マルチバイト文字列拡張モジュール

    - name: MariaDBインストール
      yum:
        name: ['mariadb-5.5.60', 'mariadb-server-5.5.60', 'php-mysqlnd-5.4.16']
        state: present
        # php-mysqlnd: MariaDB用ドライバ

    - name: 最新のRubyインストール用パッケージインストール
      yum:
        name: ['centos-release-scl-rh-2-3*', 'centos-release-scl-2-3*']
        state: present
        # centos-release-scl-rh: RHELSC互換の各種パッケージ
        # centos-release-scl:    CentOS SCLo SIGが提供するパッケージ

    - name: Rubyインストール
      yum:
        name: ['rh-ruby25-ruby', 'rh-ruby25-ruby-devel']
        state: present

    - name: 環境設定ファイル追記
      lineinfile:
        dest: ~/.bashrc
        line: 'source /opt/rh/rh-ruby25/enable'

    - name: 環境設定ファイル再読み込み
      shell: source ~/.bashrc

    - name: Railsで必要なパッケージインストール
      yum:
        name: ['libxml2-devel', 'sqlite-devel', 'nodejs']
        # nodejs: railsで必要なGemパッケージ(therubyracer)がインストールされる

    - name: Ruby Gems インストール
      gem:
        name: "{{ item }}"
        user_install: no                        # システム領域にインストール
        state: present
      with_items:
        - bundler
        - rake                                  # serverspecに必要なライブラリ
        - serverspec                            # サーバ構成テストツール
        - rails

    - name: Python3インストール
      yum:
        name: ['python36', 'python36-pip', 'MySQL-python-1.2.5']
        state: present

    - name: pipアップグレード済みなら実施しない
      stat:
        path: /usr/bin/pip3
      register: pip3

    - name: pipのアップグレード
      pip:
        name: pip
        executable: /usr/bin/pip3
        state: latest                             # 最新のバージョンにアップデート
      when: pip3.stat.exists

    - name: phpテストページの作成
      copy:
        src: phpinfo.php
        dest: /var/www/html/phpinfo.php

    - name: httpプロトコル開放
      firewalld:
        service: http
        state: enabled
        permanent: true

    - name: 3000番ポート開放
      firewalld:
        port: 3000/tcp
        state: enabled
        permanent: true

    - name: 各種サービスを再起動し、自動起動を有効化
      service:
        name: "{{ item }}"
        state: restarted
        enabled: yes
      with_items:
        - httpd
        - mariadb
        - firewalld

    - name: ~/.my.cnfを配置(MySQL設定ファイル)
      become_user: root                         # 該当ユーザへsudo
      template:
        src: my.cnf.j2
        dest: ~/.my.cnf
        mode: 0600

    - name: MySQL rootユーザのパスワードを設定
      mysql_user:
        name: root
        password: "{{ db_password }}"
        check_implicit_admin: yes               # ノンパスでrootログインを試みる

    - name: MySQL DB作成
      mysql_db:
        login_user: root
        login_password: "{{ db_password }}"
        name: "{{ database_name }}"
        state: present                          # 存在しない場合のみ作成

    - name: MySQLユーザの作成及びDBへの権限付与
      mysql_user:
        login_user: root
        login_password: "{{ db_password }}"
        name: "{{ db_username }}"
        password: "{{ db_password }}"
        priv: "{{ database_name }}.*:ALL"
        state: present

 

Playbookの内容確認

# ansible-playbook web-01_lamp_playbook.yml --syntax-check		# 構文チェック
playbook: localhost_lamp_playbook.yml							# エラーが表示されないことを確認

# ansible-playbook web-01_lamp_playbook.yml --list-task			# タスクの一覧を取得
playbook: web-01_lamp_playbook.yml

  play #1 (web-01): LAMP環境構築(さくらのクラウド)      TAGS: []
    tasks:
      PHPインストール   TAGS: []
      MariaDBインストール       TAGS: []
      最新のRubyインストール用パッケージインストール    TAGS: []
      Rubyインストール  TAGS: []
      環境設定ファイル追記      TAGS: []
      環境設定ファイル再読み込み        TAGS: []
      Railsで必要なパッケージインストール       TAGS: []
      Ruby Gems インストール    TAGS: []
      Python3インストール        TAGS: []
      pipアップグレード済みなら実施しない       TAGS: []
      pipのアップグレード       TAGS: []
      phpテストページの作成     TAGS: []
      httpプロトコル開放        TAGS: []
      3000番ポート開放  TAGS: []
      各種サービスを再起動し、自動起動を有効化  TAGS: []
      ~/.my.cnfを配置(MySQL設定ファイル)        TAGS: []
      MySQL rootユーザのパスワードを設定        TAGS: []
      MySQL DB作成      TAGS: []
      MySQLユーザの作成及びDBへの権限付与       TAGS: []

# ansible-playbook web-01_lamp_playbook.yml --check				# ドライラン

PLAY [LAMP環境構築(さくらのクラウド)] *******************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************
ok: [web-01]

TASK [PHPインストール] ****************************************************************************************************************
changed: [web-01]

TASK [MariaDBインストール] ************************************************************************************************************
changed: [web-01]

TASK [最新のRubyインストール用パッケージインストール] ************************************************************************************************
changed: [web-01]

TASK [Rubyインストール] ***************************************************************************************************************
fatal: [web-01]: FAILED! => {"changed": false, "msg": "No package matching 'rh-ruby25-ruby' found available, installed or updated", "rc": 126, "results": ["No package matching 'rh-ruby25-ruby' found available, installed or updated"]}

PLAY RECAP **********************************************************************************************************************
web-01                     : ok=4    changed=3    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

ドライランなので、[最新のRubyインストール用パッケージインストール]が実際には実行されていない為、[Rubyインストール]のところでエラーとなります。
 

実行結果

# ansible-playbook web-01_lamp_playbook.yml

PLAY [LAMP環境構築(さくらのクラウド)] *******************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************
ok: [web-01]

TASK [PHPインストール] ****************************************************************************************************************
changed: [web-01]

TASK [MariaDBインストール] ************************************************************************************************************
changed: [web-01]

TASK [最新のRubyインストール用パッケージインストール] ************************************************************************************************
changed: [web-01]

TASK [Rubyインストール] ***************************************************************************************************************
changed: [web-01]

TASK [環境設定ファイル追記] ***************************************************************************************************************
changed: [web-01]

TASK [環境設定ファイル再読み込み] ************************************************************************************************************
changed: [web-01]

TASK [Railsで必要なパッケージインストール] *****************************************************************************************************
changed: [web-01]

TASK [Ruby Gems インストール] *********************************************************************************************************
changed: [web-01] => (item=bundler)
changed: [web-01] => (item=rake)
changed: [web-01] => (item=serverspec)
changed: [web-01] => (item=rails)

TASK [Pythonインストール] *************************************************************************************************************
changed: [web-01]

TASK [pipアップグレード済みなら実施しない] ******************************************************************************************************
ok: [web-01]

TASK [pipのアップグレード] **************************************************************************************************************
changed: [web-01]

TASK [phpテストページの作成] *************************************************************************************************************
changed: [web-01]

TASK [httpプロトコル開放] **************************************************************************************************************
changed: [web-01]

TASK [3000番ポート開放] ***************************************************************************************************************
changed: [web-01]

TASK [各種サービスを再起動し、自動起動を有効化] *****************************************************************************************************
changed: [web-01] => (item=httpd)
changed: [web-01] => (item=mariadb)
changed: [web-01] => (item=firewalld)

TASK [~/.my.cnfを配置(MySQL設定ファイル)] ************************************************************************************************
changed: [web-01]

TASK [MySQL rootユーザのパスワードを設定] ***************************************************************************************************
changed: [web-01]

TASK [MySQL DB作成] ***************************************************************************************************************
changed: [web-01]

TASK [MySQLユーザの作成及びDBへの権限付与] ****************************************************************************************************
changed: [web-01]

PLAY RECAP **********************************************************************************************************************
web-01                     : ok=20   changed=18   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Serverspecを使用してサーバ構成のテストをしたいので、上記Playbookをlocalhost(ansible-01)用にコピーして編集後、実行してServerspecをインストールしておきます。

Serverspecを使用してLAMP環境が構築されていることをテスト(ansibleサーバ上)

serverspec-initを実行

# serverspec-init
Select OS type:

  1) UN*X							# CentOSなのでこちらを選択
  2) Windows

Select number: 1

Select a backend type:

  1) SSH							# SSHを選択
  2) Exec (local)

Select number: 1

Vagrant instance y/n: n				# Vagrantは使用していないので n を選択
Input target host name: web-01		# テスト対象ホストを入力
 + spec/							# specディレクトリが作成される
 + spec/web-01/
 + spec/web-01/sample_spec.rb
 + spec/spec_helper.rb

 

テストファイル作成

# cd spec/web-01
# rm sample_spec.rb								# サンプルファイルは削除

# vi httpd_spec.rb								# httpdサービスのテストファイルを作成
require 'spec_helper'

describe package('httpd') do                    # Resource(何をテストするか)
  it { should be_installed }                    # Matcher(どうあるべきか)
end

describe service('httpd') do
  it { should be_running }                      # httpdサービスが起動していること
  it { should be_enabled }                      # httpdサービスが起動時に有効になること
end

describe port(80) do
  it { should be_listening }                    # 80番ポートが空いていること
end

describe file('/var/www/html/phpinfo.php') do
  it { should be_file }                         # /var/www/html/phpinfo.phpというファイルが存在すること
  it { should be_owned_by 'root' }              # ファイルオーナーがrootであること
  it { should be_grouped_into 'root' }          # グループがrootであること
  its(:content) { should match /phpinfo/ }      # phpinfoという文字列にマッチする
end

 

テスト実行

# rake spec
(in /root)
/opt/rh/rh-ruby25/root/usr/bin/ruby -I/opt/rh/rh-ruby25/root/usr/local/share/gems/gems/rspec-support-3.8.0/lib:/opt/rh/rh-ruby25/root/usr/local/share/gems/gems/rspec-core-3.8.0/lib /opt/rh/rh-ruby25/root/usr/local/share/gems/gems/rspec-core-3.8.0/exe/rspec --pattern spec/web-01/\*_spec.rb

Package "httpd"
  should be installed			# httpdパッケージがインストールされている

Service "httpd"
  should be running				# httpdサービスが起動している
  should be enabled				# httpdサービスが起動時に有効になる

Port "80"
  should be listening			# 80番ポートが開放している

File "/var/www/html/phpinfo.php"
  should be file				# /var/www/html/phpinfo.phpというファイルが存在する
  should be owned by "root"		# ファイルオーナはroot
  should be grouped into "root"	# グループはroot
  content
    should match /phpinfo/		# phpinfoという文字列にマッチする

Finished in 1.56 seconds (files took 0.5238 seconds to load)
8 examples, 0 failures			# 0件の失敗

Serverspecについては、ドットインストールで詳しく説明されています。
Serverspec入門 (全11回:有料会員)

LAMP環境が構築されたことを確認(ansibleサーバ上)

確認スクリプト作成

# vi lamp_check.sh
#!/bin/sh

echo "### version ###"
httpd -v;          echo
php -v;            echo
mysql --version;   echo
python --version
python3 --version; echo
ruby -v;           echo

echo "### 環境設定ファイル確認 ###"
tail -2 ~/.bashrc

echo
echo "### pip list ###"
pip list

echo
echo "### firewall設定確認 ###"
firewall-cmd --list-services

echo
echo "### auto start ###"
systemctl list-unit-files | egrep "httpd|mariadb|firewalld"

echo
echo "### service status ###"
systemctl status httpd mariadb firewalld | egrep " httpd.service | mariadb.service | firewalld.service |Active"

echo
echo "### DB確認 ###"
mysql -uwpadmin -pwpadmin -e'show databases;'

echo
echo "### Webサーバ確認 ###"
echo http://localhost
echo http://localhost/phpinfo.php

 

確認スクリプト実行

# chmod u+x lamp_check.sh			# 実行権付与
# ./lamp_check.sh
### version ###
Server version: Apache/2.4.6 (CentOS)
Server built:   Apr 24 2019 13:45:48

PHP 5.4.16 (cli) (built: Oct 30 2018 19:30:51)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

mysql  Ver 15.1 Distrib 5.5.60-MariaDB, for Linux (x86_64) using readline 5.1

Python 2.7.5
Python 3.6.8

ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]

### 環境設定ファイル確認 ###
fi
source /opt/rh/rh-ruby25/enable

### pip list ###
Package    Version
---------- -------
pip        19.1.1
setuptools 39.2.0

### firewall設定確認 ###
ssh dhcpv6-client http

### auto start ###
firewalld.service                             enabled
httpd.service                                 enabled
mariadb.service                               enabled

### service status ###
● httpd.service - The Apache HTTP Server
   Active: active (running) since 火 2019-05-21 02:31:19 JST; 3min 6s ago
● mariadb.service - MariaDB database server
   Active: active (running) since 火 2019-05-21 02:31:24 JST; 3min 0s ago
● firewalld.service - firewalld - dynamic firewall daemon
   Active: active (running) since 火 2019-05-21 02:31:26 JST; 2min 58s ago

### DB確認 ###
+--------------------+
| Database           |
+--------------------+
| information_schema |
| test               |
| wp                 |
+--------------------+

### Webサーバ確認 ###
#http://localhost
#http://localhost/phpinfo.php

下記URLにアクセスして、Apacheのテストページが表示されることを確認
http://IPアドレス/

下記URLにアクセスして、PHP情報が表示されることを確認
http://IPアドレス/phpinfo.php

ヒデをフォローする
☂☂☂ボツワナに恵みの雨を☂☂☂
タイトルとURLをコピーしました