severspec入門
Serverspec
Apache,PHP,MySQL,Nagiosをインストールして インストールされているかをテストしていきます。
ServerspecはRubyが必要なのでインストールをします。 こちらを参考にインストールしてみてください。
Rubyをインストールしたら、 Ruby用のgemというソフトウェアリポジトリからServerspecをインストールします。
# yum install rubygems
# gem install serverspec
インストール完了したら Serverspec用にディレクトリを作成し、テストをしてみます。
# mkdir ~/servertest # cd servertest/ # serverspec-init Select OS type: 1) UN*X 2) Windows Select number: 1 Select a backend type: 1) SSH 2) Exec (local) Select number: 1 Vagrant instance y/n: n Input target host name: web + spec/ + spec/web/ + spec/web/sample_spec.rb + spec/spec_helper.rb + Rakefile + .rspec
rake spec実行時にエラーが出たのでまとめる
- "set :request_pty, true"を書いてくれ
spec_helper.rb
に追記して事なきを得ました。
Please write "set :request_pty, true" in your spec_helper.rb or other appropriate file.
- HighLine か Termiosをインストールしてくれ
gem install highline
で事なきを得ました。
Text will be echoed in the clear. Please install the HighLine or Termios libraries to suppress echoed text.
- passwordかlocalhostを記入してくれ
Wrong sudo password! Please confirm your password on localhost.
これはこちらを参考にしました。CentOS 6.5でserverspecサーバ構築 その2 こちらも参考【入門】serverspecでSSH経由でリモートホストにspec流す sudoパスワードを聞かれるようにしないといけないようですね。 rake specのコマンドを少し変えれば良いらしい。
$ SUDO_PASSWORD=xxxxxxxx rake spec
もしくは
$ ASK_SUDO_PASSWORD=1 rake spec
これでOK。
これらのエラーメッセージは環境によっては聞かれなかったので rubyのバージョンとかが原因なのかなあ。
サンプルのテストファイルを削除なり、 名前変更するなりしておきましょう。 書き方の参考に読んでおくのもよいです。
# mv sample_spec.rb{,.bak}
Apacheインストール
serverspecでApacheインストールのテストを書きます。
$ vi httpd_spec.rb require 'spec_helper' describe package('httpd') do it { should be_installed } end
テストが通るようにApacheをyumでインストールして、 サービスを起動させます。
# yum install httpd # service httpd status httpd は停止しています # service httpd start httpd を起動中: httpd: apr_sockaddr_info_get() failed for shuhei httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName [ OK ] # chkconfig --list |grep htt httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off # chkconfig httpd on # chkconfig --list |grep htt httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
PHPインストール
php、php-devel、php-mbstring、php-gd
が入っているテストを書きます。
require 'spec_helper' %w(php php-devel php-mbstring php-gd).each do |pkg| describe package(pkg) do it { should be_installed } end end
yumでインストールします。
# yum install php php-devel php-mbstring php-gd
MySQL5.6インストール
MySQLのインストールには2通りあります。
yumとrpmでインストールの2種類あり、 MySQL5.6まではインストール方法でパッケージやサービス名に 差異があるとのこと。 5.7からは差異はないらしい
yumコマンドでのインストールは簡単なのでおすすめですが、
インストールされるパスが固定されるので、
1台のサーバに複数のMySQLをインストールすることができないです。
また、yum upgrade
時にMySQLサーバがマイナーバージョンアップされることがあるらしく、
インストール後に無効化する必要があります。
メジャーバージョンアップはされないように、メジャーバージョンアップごとに
違うリポジトリ名が割り当てられています。
(今回は1台のサーバにMySQLサーバ2台たてて、レプリケーションを行いたいので、 rpmパッケージでインストールしていきます。)
- rpmパッケージを使用したインストール
MySQLはサイトからダウンロードします。
/usr/local/src
配下にRed Hat Enterprise Linux 6 / Oracle Linux 6 (x86, 64-bit), RPM Bundle
をインストールします。
# cd /usr/local/src/ # wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-5.6.32-1.el6.x86_64.rpm-bundle.tar # tar xvf MySQL-5.6.32-1.el6.x86_64.rpm-bundle.tar MySQL-shared-5.6.32-1.el6.x86_64.rpm MySQL-test-5.6.32-1.el6.x86_64.rpm MySQL-server-5.6.32-1.el6.x86_64.rpm MySQL-shared-compat-5.6.32-1.el6.x86_64.rpm MySQL-client-5.6.32-1.el6.x86_64.rpm MySQL-embedded-5.6.32-1.el6.x86_64.rpm MySQL-devel-5.6.32-1.el6.x86_64.rpm
パッケージを-i
でインストールします。
# rpm -i MySQL-*.rpm 警告: MySQL-client-5.6.32-1.el6.x86_64.rpm: ヘッダ V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY エラー: 依存性の欠如: MySQL-devel は mysql-devel-5.1.73-7.el6.x86_64 と競合します。
MySQL-devel は mysql-devel-5.1.73-7.el6.x86_64 と競合します。
なんてエラーがでました。mysql-devel-5.1.73-7.el6.x86_64
なんて入れた覚えはない。
-e
でアンインストールしてみるが、インストールされていないとのこと。。。
# rpm -e mysql-devel-5.1.73-7.el6.x86_64.rpm エラー: パッケージ mysql-devel-5.1.73-7.el6.x86_64.rpm はインストールされていません。
# yum remove mysql-libs
インストール成功
# rpm -i MySQL-*.rpm
サービスを起動させて3306ポートでLISTENしていることを確認 rpmインストールなのでサービス名がmysqlです。 yumインストールもしくは5.7はmysqldになります。
# service mysql status ERROR! MySQL is not running # service mysql start Starting MySQL SUCCESS! [root@shuhei src]# service mysql status SUCCESS! MySQL.. running (17092) # ps auxf |grep mysql root 17204 0.0 0.0 103320 852 pts/2 S+ 17:29 0:00 \_ grep mysql root 16989 0.0 0.1 11340 1364 pts/2 S 17:29 0:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/lib/mysql/shuhei.pid mysql 17092 2.2 44.2 1013188 451848 pts/2 Sl 17:29 0:00 \_ /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/lib/mysql/shuhei.err --pid-file=/var/lib/mysql/shuhei.pid # netstat -atnp |grep mysql tcp 0 0 :::3306 :::* LISTEN 17092/mysqld
MySQLのプロセスが起動されているか、ポート接続しているかテストを書きます
require 'spec_helper' describe service('mysqld') do it { should be_enabled } it { should be_running } end describe port(3306) do it { should be_listening } end describe service('mysql') do it { should be_enabled } it { should be_running } end describe port(3308) do it { should be_listening } end
Nagiosインストール
nagiosがインストールされているテストを書きます。
require 'spec_helper' describe service('nagios') do it { should be_enabled } it { should be_running } end
/usr/local/src
配下に
最新版4.2.0をサイトからインストールします。
# wget https://assets.nagios.com/downloads/nagioscore/releases/nagios-4.2.0.tar.gz#_ga=1.247838018.451693304.1472123299 # wget https://nagios-plugins.org/download/nagios-plugins-2.1.2.tar.gz#_ga=1.179877985.451693304.1472123299
必要なパッケージをインストール
yum install gcc glibc glibc-common yum install gd gd-devel
Nagiosユーザとグループを作成
# /usr/sbin/useradd -m nagios # passwd nagios # /usr/sbin/groupadd nagcmd # /usr/sbin/usermod -a -G nagcmd nagios # /usr/sbin/usermod -a -G nagcmd apache # less /etc/passwd # less /etc/group
ダウンロードしたfileを解凍
tar xzf nagios-4.2.0.tar.gz cd nagios-4.2.0
作成したグループを指定してconfig scriptを実行
./configure --with-command-group=nagcmd
コンパイル実行
make all
インストール実行
make install make install-init make install-config make install-commandmode
web configをインストール
make install-webconf
Nagiosのweb画面にログインユーザーnagiosadminを作成
htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin
Apache再起動
service httpd restart
pluginのコンパイルとインストール
# ./configure --with-nagios-group=nagios --with-mysql=/usr/bin/mysql checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... configure: error: newly created file is older than distributed files! Check your system clock
OSとハードの時間が実際の時間とずれているのが原因でインストールに失敗する (2016/08/25)
# date 2016年 7月 24日 日曜日 18:17:55 JST # hwclock 2016年07月24日 18時17分58秒 -0.524383 秒
時間を合わせればインストールできる。
date -s "08/25 20:39 2016" 2016年 8月 25日 木曜日 20:39:00 JST date 2016年 8月 25日 木曜日 20:39:02 JST hwclock 2016年07月24日 18時20分17秒 -0.148454 秒 hwclock -w # hwclock --systohc # hwclock 2016年08月25日 20時39分16秒 -0.051022 秒
nagiosがインストールされているテストを書きます。
require 'spec_helper' describe service('nagios') do it { should be_enabled } it { should be_running } end
Ansible入門
Ansible
Ansibleサーバのhostを立てて、 AnsibleでWEBとDBサーバを構築していく。 Ansibleでは管理される側にはPythonが入っていて、 あとはSSH接続ができればよい。
- やっていくこと
Ansibleのインストール SSH接続確認 Inventoryファイル編集 # どのサーバを管理するのか記述する ansible.cfg編集 # Ansibleの設定ファイル Playbook編集 # 管理するサーバの構成を記述
- 構成
HOSTサーバ:Ansible WEBサーバ:Use,Apache,PHP DBサーバ:Use,MySQL
Vagrantfileは以下の設定を追記します。
# 変更箇所 # config.vm.box = "bento/centos-6.7" # 追加箇所 config.vm.define "host" do |node| node.vm.box = "bento/centos-6.7" node.vm.hostname = "host" node.vm.network :private_network, ip: "192.168.43.51" end config.vm.define "web" do |node| node.vm.box = "bento/centos-6.7" node.vm.hostname = "web" node.vm.network :private_network, ip: "192.168.43.52" end config.vm.define "db" do |node| node.vm.box = "bento/centos-6.7" node.vm.hostname = "db" node.vm.network :private_network, ip: "192.168.43.53" end
サーバを立ち上げ、立ち上がっているのを確認
$ vagrant up $ vagrant status Current machine states: host running (virtualbox) web running (virtualbox) db running (virtualbox)
Ansibleサーバのhostへssh接続をします。
$ vagrant ssh host
yumでAnsibleインストールできなかった。
$ sudo yum install ansible (略) パッケージ ansible は利用できません。 エラー: 何もしません
epelリポジトリをインストールします
$ sudo yum install epel-release
これはrpmでインストールしてもよい。 https://dl.fedoraproject.org/pub/epel/ 最新はhttps://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpmですね。(2016/08現在)
wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm sudo rpm -Uvh epel-release-latest-7.noarch.rpm
これでもう一度yumでAnsibleをインストールすればできるはず
$ sudo yum install ansible
Ansibleインストール完了
$ ansible --version ansible 2.1.1.0 config file = /etc/ansible/ansible.cfg configured module search path = Default w/o overrides
SSH接続を鍵認証で行えるようにします。
.ssh/config
を作成します。
またパーミッションも変更します。
$ vi .ssh/config Host web HostName 192.168.43.52 User vagrant Host db HostName 192.168.43.53 User vagrant $ ll .ssh/config -rw-rw-r--. 1 vagrant vagrant 67 8月 29 10:34 2016 .ssh/config $ chmod 600 .ssh/config ll .ssh/config -rw-------. 1 vagrant vagrant 67 8月 29 10:34 2016 .ssh/config
次に秘密鍵と公開鍵を作成しwebとdbに公開鍵をコピーします。 コピーしたらhostnameを指定してSSH接続できることを確認
$ ssh-keygen -t rsa $ ssh-keygen -t rsa $ ssh-copy-id web $ ssh web $ ssh-copy-id db $ ssh db
hostsというinventoryファイルを作成し host側でAnsibleコマンドを実行します。 hostsにはwebとdbの情報を記載します。 ここで[グループ名]でグループをつくることができます。 Ansibleコマンドを実行するときallやhostname指定またはグループ指定ができるようになります。
$ vi hosts [web] 192.168.43.52 [db] 192.168.43.53
ansible 対象サーバ -i inventoryファイル(フルパス) -m module名
ex.ping module
$ ansible all -i hosts -m ping 192.168.43.53 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.43.52 | SUCCESS => { "changed": false, "ping": "pong" }
またansible.cfg
にinventoryファイルを指定すれば省略可能です。
-i を抜かしてコマンドが実行できます。
$ ansible all -m ping
$ ansible all -m ping 192.168.43.52 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.43.53 | SUCCESS => { "changed": false, "ping": "pong" }
playbookにサーバにしたい処理を書きます
今回はhogeユーザを追加してみます。
YAMLファイルで記述します。
一行目の「---」YAMLファイルであることを指す
「- hosts」に対象サーバを指定する。今回は「all」で全台へ
管理者権限が必要なので「sudo: yes」とする。
タスクを実行するために「tasks:」モジュールを指定し、
タスクに名前をつけておきます。
- name: add a new user
とし、
userモジュールとnameオプションでhogeユーザを追加します。
$ vi playbook.yml $ cat playbook.yml --- - hosts: all sudo: yes tasks: - name: add a new user user: name=hoge $ ansible-playbook playbook.yml [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.52] ok: [192.168.43.53] TASK [add a new user] ********************************************************** changed: [192.168.43.52] changed: [192.168.43.53] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=2 changed=1 unreachable=0 failed=0 192.168.43.53 : ok=2 changed=1 unreachable=0 failed=0
モジュールは冪等なのですでにhogeユーザがいたら、何もしません。
2回目を実行してもOKで返ってきますが、changed=0
となっていることがわかります。
シェルとかだと既にユーザがいたらおかしな挙動をするかもしれませんね。
ここがAnsibleの利点で安全にplaybookを何度も実行できます。
実際にhogeユーザが追加されていることも確認できました。
$ ansible-playbook playbook.yml [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.52] ok: [192.168.43.53] TASK [add a new user] ********************************************************** ok: [192.168.43.52] ok: [192.168.43.53] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=2 changed=0 unreachable=0 failed=0 192.168.43.53 : ok=2 changed=0 unreachable=0 failed=0 $ ssh web Last login: Wed Aug 31 22:12:23 2016 from 192.168.43.51 cat /etc/passwd |grep hoge hoge:x:501:501::/home/hoge:/bin/bash
stateオプションを使ってみる。 stateそれが存在するかどうかを指定できる。 hogeユーザが存在しないとする。
user: name=hoge state=absent
実行してみるとユーザが消えていることが確認できる。
[vagrant@host ~]$ ansible-playbook playbook.yml [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.52] ok: [192.168.43.53] TASK [add a new user] ********************************************************** changed: [192.168.43.52] changed: [192.168.43.53] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=2 changed=1 unreachable=0 failed=0 192.168.43.53 : ok=2 changed=1 unreachable=0 failed=0 [vagrant@host ~]$ ssh web ^[[ALast login: Wed Aug 31 22:37:46 2016 from 192.168.43.51 [vagrant@web ~]$ cat /etc/passwd |grep hoge [vagrant@web ~]$ logout
ansible-playbookのオプションを確認
--syntax-check
はPlaybookの文法チェック
$ ansible-playbook playbook.yml --syntax-check [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. playbook: playbook.yml
--list-task
はタスク一覧を表示
$ ansible-playbook playbook.yml --list-task [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. playbook: playbook.yml play #1 (all): all TAGS: [] tasks: add a new user TAGS: []
--check
はドライランを実行
$ ansible-playbook playbook.yml --check
Playbookでは変数も使えます。Playbookを使い回すときに便利になる。
今回はユーザ名を変数で扱ってみます。
[tasks:]の前に[vats:]というのをつけて
キーと値を管理します。
ここではusername: hoge
変数とするときは{{キー}}
とすればよい
$ cat playbook.yml --- - hosts: all sudo: yes vars: username: hoge tasks: - name: add a new user user: name={{username}} ]$ ansible-playbook playbook.yml [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.52] ok: [192.168.43.53] TASK [add a new user] ********************************************************** changed: [192.168.43.52] changed: [192.168.43.53] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=2 changed=1 unreachable=0 failed=0 192.168.43.53 : ok=2 changed=1 unreachable=0 failed=0
実行時にユーザに変数の値を入力させることもできます。 「vars: prompt」として「username: "Enter username"」とする。 これで実行時にユーザ名が聞かれます。
$ cat playbook.yml --- - hosts: all sudo: yes # vars: # username: hoge vars_prompt: username: "Enter username" tasks: - name: add a new user user: name={{username}} $ ansible-playbook playbook.yml [DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. [DEPRECATION WARNING]: Using the 'short form' for vars_prompt has been deprecated. This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. Enter username: hoge PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.43.53] ok: [192.168.43.52] TASK [add a new user] ********************************************************** ok: [192.168.43.52] ok: [192.168.43.53] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=2 changed=0 unreachable=0 failed=0 192.168.43.53 : ok=2 changed=0 unreachable=0 failed=0
WEBにApacheをインストールするplaybookを書きます。
yumモジュールを使い、state=latest
とすると最新版をインストールします。
serviceモジュールを使い、再起動時に自動起動するように設定します。
--- - hosts: all sudo: yes tasks: - name: add a new user user: name=hoge - hosts: web sudo: yes tasks: - name: install apache yum: name=httpd state=latest - name: start apache and enabled service: name=httpd state=started enabled=yes ~
WEBブラウザのURLに192.168.43.52
でアクセスするとApacheの画面が出てきます。
次はApacheのドキュメントルートの所有者を変更し、 ファイルを置いてWEBブラウザ上から確認してみます。 最初に適当にindex.htmlを作成してかた、 playbookに書いていきます。
まずは、ドキュメントルートの所有者変更は
ファイルやディレクトリに関するfileモジュールを使います。
対象ディレクトリとownerを指定し、recurse=yes
にすることで
再帰的に反映されます。
次に、index.htmlファイルを転送するために copyモジュールを使い、 対象ファイルと、対象ディレクトリ、所有者を指定します。
--- - hosts: all sudo: yes tasks: - name: add a new user user: name=hoge - hosts: web sudo: yes tasks: - name: install apache yum: name=httpd state=latest - name: start apache and enabled service: name=httpd state=started enabled=yes - name: change owner file: dest=/var/www/html owner=vagrant recurse=yes - name: copy index.html copy: src=./index.html dest=/var/www/html/index.html owner=vagrant
ansible-playbookを実行するとエラーが出ました。
TASK [copy index.html] ********************************************************* fatal: [192.168.43.52]: FAILED! => {"changed": false, "checksum": "82a4c7e6c69f12b6fdc25ec54a16ef7a1bfbecaf", "failed": true, "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"}
libselinux-python
がインストールされていないとエラーが出たので、
WEBとDBに対してインストールするようにplaybook追記します。
--- - hosts: all sudo: yes tasks: - name: add a new user user: name=hoge - name: install libselinux-python yum: name=libselinux-python state=latest
これで成功。 WEBブラウザで確認し反映されていることを確認。
PHPパッケージインストール
複数のパッケージをインストールする際、
yumモジュールをを何度も書くことよりも、
インストールしたいパッケージをリスト化したほうがよいです。
nameのあとに{{item}}
として、
with_items
を使い、リスト化します。
これでリスト化したパッケージが一つずつ{{item}}
に代入され
yumが実行されインストールされます。
Apache再起動もplaybook上で行います。 serviceモジュールで再起動しますが、 notifyとhandlersモジュールを使い、 タスクで変更があった場合、再起動するようにします。 handlersは最後に一回だけ呼ばれるもので、 複数の箇所からnotifyで呼ばれても実行するのは最後の一回です。 また、PHPファイルを作成し、WEBに転送して、WEBブラウザ上で表示されるか確認し、 Apache再起動されているか確認します。
- name: install php packages yum: name={{item}} state=latest with_items: - php - php-devel - php-mbstring - php-mysql notify: - restart apache - name: copy hello.php copy: src=./hello.php dest=/var/www/html/hello.php owner=vagrant handlers: - name: restart apache service: name=httpd state=restarted
PHPのパッケージインストールと ファイルの転送、Apache再起動が実施されています。
TASK [install php packages] **************************************************** changed: [192.168.43.52] => (item=[u'php', u'php-devel', u'php-mbstring', u'php-mysql']) TASK [copy hello.php] ********************************************************** changed: [192.168.43.52] RUNNING HANDLER [restart apache] *********************************************** changed: [192.168.43.52] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=11 changed=3 unreachable=0 failed=0 192.168.43.53 : ok=3 changed=0 unreachable=0 failed=0
もう一度ansible-playbookを実行してみると 既にPHPパッケージがインストールされているので、 notifyからhandlersが呼ばれていないので、 Apache再起動されていないのが確認できます。
TASK [install php packages] **************************************************** ok: [192.168.43.52] => (item=[u'php', u'php-devel', u'php-mbstring', u'php-mysql']) TASK [copy hello.php] ********************************************************** ok: [192.168.43.52] PLAY RECAP ********************************************************************* 192.168.43.52 : ok=10 changed=0 unreachable=0 failed=0 192.168.43.53 : ok=3 changed=0 unreachable=0 failed=0
DBへMySQLをインストールします。
- hosts: db sudo: yes tasks: - name: install mysql yum: name=mysql-server state=latest - name: start mysql and enabled service: name=mysqld state=started enabled=yes
DBでMySQLがインストールされていることを確認
$ ssh db Last login: Thu Sep 1 10:11:31 2016 from 192.168.43.51 mysql --version mysql Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1
MySQLデータベースを作成し、ユーザを設定します。
mysql_db
モジュールを使用します。
ユーザはmysql_user
を使用します。
priv
でデータベースの全てのテーブルに対し、権限を付与します。
- name: create a database mysql_db: name=mydb state=present - name: create a name for mydb mysql_user: name=dbuser password=******** priv=mydb.*:ALL state=present
データベースを作るときにpython mysqldb
が必要らしいのでインストールする。
TASK [create a database] ******************************************************* fatal: [192.168.43.53]: FAILED! => {"changed": false, "failed": true, "msg": "the python mysqldb module is required"}
変数を使ってまとめてインストールします。
tasks: - name: install mysql yum: name={{item}} state=latest with_items: - mysql-server - MySQL-python
DBにSSH接続してデータベースが作成されていることを確認
$ ssh db Last login: Thu Sep 1 10:19:04 2016 from 192.168.43.51 $ mysql -u dbuser -p mydb Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.1.73 Source distribution Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mydb | | test | +--------------------+ 3 rows in set (0.00 sec) mysql> exit Bye
itamaeとvagrantでやるテスト駆動--その1-Apache,PHP編
rake spec
を実行しつつItamaeで構築
hostとwebというサーバをたてて
hostにserverspec
とItamae
をインストールし、
webを構築して、テストをしていきます。
mkdir serverspec_test cd serverspec_test
Vagrantfileを作成します。
vagrant init bento/centos-6.7 vi Vagrantfile
以下のように編集
# config.vm.box = "bento/centos-6.7" #コメントアウトする ## 以下の設定を追記して hostとwebにIPアドレス割り振る config.vm.define "host" do |node| node.vm.box = "bento/centos-6.7" node.vm.hostname = "host" node.vm.network :private_network, ip: "192.168.33.10" end config.vm.define "web" do |node| node.vm.box = "bento/centos-6.7" node.vm.hostname = "web" node.vm.network :private_network, ip: "192.168.33.11" end
vagrantを立ち上げてログインをします
$ vagrant up $ vagrant status $ vagrant ssh host
ホストからWEBへssh接続できるようにします。
[vagrant@host ~]$ ssh-keygen -N "" -f ~/.ssh/id_rsa [vagrant@host ~]$ cat << FIN >> ~/.ssh/config > Host web > HostName 192.168.33.11 > FIN [vagrant@host ~]$ chmod 600 .ssh/config [vagrant@host ~]$ ssh-copy-id web [vagrant@host ~]$ ssh web vagrant@192.168.33.11's password: [vagrant@web ~]$ uname -n web
環境構築をしていきます。 dotinstallのgitからミドル一式をインストールして、 gemでitamaeとserverspecをインストールします。
git clone https://github.com/dotinstallres/centos65.git $ cd centos65 $ ./run.sh $ exec $SHELL -l $ gem list $ gem install itamae serverspec $ gem list
作業ディレクトリを任意の場所に作っておきます。 また、Itamaeで使用するファイルも予め作っておきます。
$ mkdir myproject $ cd myproject/ $ mkdir cookbooks $ cd cookbooks/ $ touch recipe.rb
serverspec-init
でテスト対象への
OSや接続方法、ホスト名などを入力します。
$ serverspec-init Select OS type: 1) UN*X 2) Windows Select number: 1 Select a backend type: 1) SSH 2) Exec (local) Select number: 1 Vagrant instance y/n: n Input target host name: web + spec/ + spec/web/ + spec/web/sample_spec.rb + spec/spec_helper.rb + Rakefile + .rspec
サンプルのテストファイルは削除し、 位置から空のテストファイルを作成していきましょう。
$ cd spec/ $ cd web/ $ rm sample_spec.rb $ touch httpd_spec.rb
httpd_spec.rb
にApacheのテストを書きます。
$ vi httpd_spec.rb
require 'spec_helper' describe package('httpd') do it { should be_installed } end
ここでテストを実行してテストが正常に失敗することを確認します。
$ rake spec
テストが通るように、
recipe.rb
にApacheインストールの記述をします。
$ vi cookbooks/recipe.rb
package 'httpd'
itamaeを実行してテストが通ることを確認します。
$ itamae ssh -h web cookbooks/recipe.rb -n $ itamae ssh -h web cookbooks/recipe.rb $ rake spec
テストの際,Rspecの記法として ResourceとMatcherが出てきました。 これらの種類は公式サイトのRESOUCE TYPEから確認できます。
Resource - 何をテストするのか - httpdのpackage
Matcher - どういう状態 - be_installed
まずはhttpdが自動起動していて、80番ポートでLISTENしているかテストを書きます。
be_enable
で自動起動の設定で、be_running
がスタートしているかです。
require 'spec_helper' describe service('httpd') do it { should be_enabled } it { should be_running } end describe port(80) do it { should be_listening } end
それではhttpdを自動起動させます。
:enable :start
で自動起動させます。
デフォルトで80番ポートでLISTENします。
package 'httpd' service 'httpd' do action [:enable, :start] end
rake speckを実行してテストが成功することを確認
ファイルを転送して、中身のテストをしていきます。
index.htmlが存在して、中身がHello World
という文字列が含まれているか
テストを書きます。
オーナとグループがapache
であることも確認します。
describe file('/var/www/html/index.html') do it { should be_file } it { should be_owned_by 'apache' } it { should be_grouped_into 'apache' } its(:content) { should match /Hello World/ } end
filesフォルダを作り、 そこに転送用のindex.htmlを書きます。
$ mkdir cookbooks/files $ vi cookbooks/files/index.html <html> Hello World </html>
Itamaeではオーナとグループがapache
のindex.html
/var/www/html/
配下に転送させます。
remote_file '/var/www/html/index.html' do owner 'apache' group 'apache' end
rake specを実行し、テストが成功することを確認
パッケージをまとめてインストールさせて、テストを実施する
phpのテストを書いてみます。
新しくテストファイルを書きます。
eachメソッドを使いパッケージをインストールします。
php、php-devel、php-mbstring、php-gd
が入っていることを確認します。
require 'spec_helper' %w(php php-devel php-mbstring php-gd).each do |pkg| describe package(pkg) do it { should be_installed } end end
Itamaeのレシピには以下を追加してパッケージをインストールさせます。
%w(php php-devel php-mbstring php-gd).each do |pkg| package pkg end
rake speqを実行して、 PHPがインストールしたことを確認します。
PHPがインストールされたことを確認したら、 設定ファイルの中身を確認します。
php_configというリソースを使っていきます。
タイムゾーンがAsia/Tokyo
であることを確認してみる
設定項目はdata.timezode
値を確認するにはits(:value)
を使います。
shouldで文字列が同じでないといけないと書きます。
describe php_config('date.timezone') do its(:value) { should eq 'Asia/Tokyo' } end
Itamaeではレシピに以下を追記
/etc/php.ini
をaction :edit
で編集
blockを使い|content|
で破壊的メソッドで置換をします。
コメントアウトになっているdate.timezone
を
'date.timezone = Asia/Tokyo'に置換
file '/etc/php.ini' do action :edit block do |content| content.gsub!(';date.timezone =', 'date.timezone = Asia/Tokyo') end end
rake specを実行し、 ファイルが編集されていることを確認します。
次に、ディレクトリが存在するかテストしてみます。
ファイルやディレクトリを確認するテストファイルを作成します。
file()
リソースを使い、Matcherでbe_directory
を使えばテストできますが、
commandリソースでコマンドを実行させて確認することもできる
今回ならlsコマンドを実行して、その結果をテストする
its(:stdout)
で標準出力をテストできます。
今回は空白とディレクトリ名と行末の正規表現でテストします。
require 'spec_helper' # describe file('/home/vagrant/myapp') do # it { should be_directory } # end describe command('ls -la /home/vagrant') do its(:stdout) { should match /\smyapp$/ } end
Itamaeのレシピではディレクトリを作成するレシピを追記します
directory '/home/vagrant/myapp'
vagrantとvirtualboxで作るローカル開発環境
VirtualBoxをインストール
Vagrantをインストール
CentOSインストール
作業ディレクトリを作成して移動します
$ mkdir MyVagrant $ cd MyVagrant $ mkdir mycentos $ cd mycentos
初期化コマンドを実行し、Vagrantfileという設定ファイルが作成されるのを確認します。 また、boxが追加されていることも確認できます。 Vagrantfileを編集してローカルIP(192.168.〜)のコメントアウトを外します。 そしたらVMを起動し、sshで接続します。
$ vagrant init bento/centos-6.7 $ ll $ vagrant box list bento/centos-6.7 (virtualbox, 2.2.7) $ vim Vagrantfile config.vm.network "private_network", ip: "192.168.xxx.xxx" $ vagrant up $ vagrant ssh
vagrant sshの時に以下のエラーメッセージが出力されました。
ssh接続の認証が失敗しているようです。
$ vagrant ssh
で接続をして、パスワードがきかれてきます。
vagrant
を入力すればログインできました。
default: Warning: Remote connection disconnect. Retrying... default: Warning: Authentication failure. Retrying... default: Warning: Authentication failure. Retrying...
dotinstallのGithubにcentos6.5のansible一式があったので それを利用しましょう。
$ sudo yum -y install git $ git clone https://github.com/dotinstallres/centos65.git $ cd centos65/ $ ./run.sh $ ruby -v -bash: ruby: コマンドが見つかりません $ exec $SHELL -l $ ruby -v ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
他にインストールされたものを確認
$ php -v PHP 5.6.24 (cli) (built: Jul 21 2016 07:42:08) Copyright (c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies $ mysql --version mysql Ver 14.14 Distrib 5.5.51, for Linux (x86_64) using readline 5.1 $ python --version Python 2.6.6 $ ruby -v ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux] $ sudo service httpd status httpd (pid 26838) を実行中...
ApacheとPHPが起動しているので、
試しにWEBページをブラウザ上に表示させてみましょう。
以下のindex.phpを/var/www/html
配下において
ブラウザ上で確認しましょう。
ブラウザのURLにサーバのIPアドレス/index.php
を打ち込んで
Hello Worldの文字が表示されることを確認します。
$ vim index.php <?php echo "Hello World";
IPアドレスではなくて、ホスト名を入力して確かめたい人は hostsファイルを修正すればできます。 IPアドレスに対してホスト名を記入すればできます。
$ vi /etc/hosts IPアドレス ホスト名
再度、URLにホスト名/index.php
で表示できることを確認
これで環境構築の設定は以上。
CentOS7のAnsibleはないようなので、 作成しておこう。
boxの削除
Macintosh:mycentos shuhei$ vagrant box list bento/centos-6.7 (virtualbox, 2.2.7) Macintosh:mycentos shuhei$ vagrant box remove bento/centos-6.7 Box 'bento/centos-6.7' (v2.2.7) with provider 'virtualbox' appears to still be in use by at least one Vagrant environment. Removing the box could corrupt the environment. We recommend destroying these environments first: default (ID: 113a639075cb4f1c8e398bf1a5bf5340) host (ID: 44374733ca5644bfb8a902c6cd73cf5c) web (ID: c5c7135a72c44ef682ed38fe8c5ed156) Are you sure you want to remove this box? [y/N] y Removing box 'bento/centos-6.7' (v2.2.7) with provider 'virtualbox'... Macintosh:mycentos shuhei$ vagrant box list There are no installed boxes! Use `vagrant box add` to add some.
Vagrantfileは残っているのでrmコマンドで削除
Macintosh:mycentos shuhei$ ll total 8 -rw-r--r-- 1 shuhei staff 3005 8 12 06:15 Vagrantfile
7月のテックの祭典
前日にPokemonGoMapに消耗して徹夜で行きました。 終日立っていたのでところどころ聞けていなかったです。 ユニークなのが会場がPokemonGOのポケステーションで イベント中はずっとルアーモジュールが使用されていました。 おかげでミニリュウとカモネギを捕まえることができましたので、 運営には感謝。
- 基調講演
- 現実が正解だ! やってみんとわからんことだらけ。 さくらのIoT企画・開発365日の軌跡。そして、次の365日へ。
さくらのIoT Platformの立ち上げに奔走したこの1年を、 チームビルディングという観点で紹介されていました。
あとブースでさくらクラウド2万円クーポンありがとうございました。
- Wantedly の文化を支えるインフラとビジネスの変化に強いインフラ
ブースに座ったまま聞けたので、最高でした。 このセッション聞けて満足して午前が終わりました。 Wantedlyのインフラチームはコードを書いて問題解決をしている。 憧れていた仕事はこういうものだったと気づいたセッションでした。 会社のポジションを気にしていたけど、どういう仕事をしたかったのかを 気づかせてくれたし、今後の生存戦略の方針が決まってきた感じがありました。 今年一年でコードをかけるインフラエンジニアになって、そういう仕事ができる 場所にいけるようやっていきが高まったセッションでした。 帰宅してから、Wantedly Tech Bookは買って読んでいます。
具体的なセッション内容は、 やぱちーでも聞いたCode Wins Argumentsの紹介から、 WantedlyでのUser Firstのお話と、Simple is Not Easyであることのおはなし。 Wantedlyの社員数と売上のグラフをみましたが、伸びかたがすごかったです。 これがグロースというものなのかと思いました。 XaaSとAWSの両方を使い、利用できるものはどんどん利用する。 HerokuやRedisやFirebaseとAWSの組み合わせなどもやっている。 これらはスピード感とコスト感などで選択しているとのこと。 規模が大きくなるに連れて、 Developerからインフラへのタスク依頼が増えてインフラ側がボトルネックになっていく。 これをどう解決するか、既存、新規アプリ関係なく、 すぐにデプロイできる環境を提供できるようにするのが、変化に強いインフラ。 自動化とTool(API)の作成して、 DeveloperがそのToolを使うようにさせて、 インフラにタスク依頼がこないようにした。 Developerに使ってもらえるように気をつけている。 herokuからAWSへの移行のような大きな変化は コマンドが変わることでDeveloperに影響がでるので、 これまでの運用の変化差異を減らせるように、 ヒアリングをして同じ結果になるようにコマンドを作成した。 Docker imageの中にChefを使ってインスタンス作成たり、 PackerでAWSのinstanceのAMIを作成などをした。 ただ、これではアプリケーションの構築部分がCode化できたが、 インフラがコードをメンテするので、インフラがボトルネックになってしまう。 TerraformeはAWS(S3/RDS/ELB etc)dnsimpleを操作させている。 WantedlyではCoreOSを使用しているが、 CoreOSを使うきっかけはDockerやRegistryのversion upが大変だから、 Officialにamiが用意されているのでCoreOSを試験運用してきた。 サーバが一台停止されたら、勝手にインスタンスが立ち上がって欲しいので、 golangでツールを作成。AWS TAGを元にsystemdにサービスを提供させるもの。
ただ、これはAutoScaleでよいのでないかしらとおもいました。
クラスタリングはすぐアプリを動かせるインフラをすぐに作れるので、 何台分でもよくて、一回限りでもよい。 Kong Archirtecture:各サービスのAPI作成するとき、 Kongに対してdeployすればよい。これはAPI Gatewayの働きをする。 API GenerateはAPIを作成してくれる。 Wantedlyのインフラチームはコードを書いて問題解決をしているとのことでした。
動画はないみたいなので、公開されているプレゼン資料を読むのが良さそうです!
- 今あえて試行錯誤しながら"車輪の再発明"をする意味
このセッションを聞こうと思って、もともと参加してたのですが、 他の人に譲らないといけないみたいな感じになりソウルジェムが濁ったのですが、 途中から聞けるようになったのでよかった。
いい話でよかったです。そしてやっているからスキル高いんだなあとも思いました。 もし、来年も同じセッションを聞いていい話と思っちゃいけないとも思いました。 今年一年で、来年このセッションを聞く必要がないようにならないといけない。 手を動かしてやっていかないといけないと思いました。
途中からだったんのですが、内容としてはプログラミング初めて写経の次はどうするのか問題。 写経の次は車輪の再発明のすすめ。 ただプログラミングのやり方がわかってきてからやったほうがよくて、 自分でプロトコル、アルゴリズムを実装するのがよい。 たとえばHTTPプロトコルのサーバやクライアントをつくるとか、 自分が普段使っているプロダクトに似ているものを作ってみる。 Apacheやkeepalivedなどなど。 これをやることでボトルネックの想像がつきやすくなってくる。 HTTPサーバの実装だったら、HTTPのRFCを読んで、知らないヘッダを読む。 keepaliveや、cache-controlについてどういうものなのかを漠然としたものから 理解することができるようになる。 HTTPサーバの自作はおすすめらしい。 ヘッダを無視して、メソッド、パス、受けたら返すようにするのを目指す。 これをやるとc10k問題がどういうものなのかが、わかってくる。 ファイルディスクリプタをセレクトでみてるからc10k問題になる。 epollでみてるのがnginx. ほかにはCGIはどのようにして動作しているのかわかる。 こういうのをやって、どれだけ役に立っているかというと毎日役立ってると思うくらい役に立っているとのこと。 自作したHTTPサーバに対して、curlやブラウザが返ってくるのは感動。 セッション中ではJavaで自作する本が出ているのをおすすめしていました。 他にはLinuxコンテナエンジンの自作をしてみる。 Dockerは巨大なので、実装することで中でどのような動きになっているか理解できる。 cgroupやchroot,vethのような技術も理解できる。 先駆者がいるので、コードを読んで参考にするのがよい。 Denaのjaillingのperlは200行ぐらいで書かれていたりする。 あとはdrootやhaconiwaなど 他に車輪の再発明としておすすめなのは、 言語処理系、LispのNosql系、プロビジョニングツール、Itamaem、ldapが大変なので、ログイン認証サーバを作ってみる。 他には監視サーバをつくてみるとかもよい。 分散システムのアルゴリズムを実装してみたりもおすすめ。 車輪の再発明はプロトコルや低レイヤなどの普遍的で長く使える技術を効率よく学べる。 似たものを作るので元のソースコードを必然的に読むことが増える。 RFCを読み解く練習にもなる。新しい実装の公開にも読み解ける。 車輪の再発明の次はなにか、それは代表的プロダクトを作ってみる。 代表的プロダクトとはあの人といえばこのプロダクトと呼ばれるもの。 車輪の再発明+アイデア=代表的プロダクトになる可能性があるのでは? 既存のソフトウェアの不満点を解決、デプロイや運用が既存のソフトウェアより簡単になっている。 抽象化しすぎると特定の規模に絞れないので、ドメインを対象に特化してみる。 書き直すならどの言語で書き直すのか?UIの考え方も重要。 ここのUIは運用する人目線のインターフェースをとらえる。 既存の言語をGOで書き直す流行りがあった。 ワンバイナリで動くので導入障壁が低い。 対話型インターフェースにしないでyをきいてこないようにすれば、 自動化の妨げにならないとか運用目線で考える。 設定ファイルや自動化が難しいツールをCruby/mrubyなどで作り直す。 気をつけよう!! 発明アンチパターン(嫌われる車輪の再発明)はやめて! 既存の劣化品を作ってプロダクションにいれてしまうことなど。 既存のモノの修正で十分済むのに新しい物をつくって導入してしまうことなど。 自分の発明にするには作ろうとしている対象の領域の深い知見が必要。 実装すればわかるのは、たいてい勝てない。 作りなおすのはアーキテクチャとしてダメなとき。 やってみた側になるには手を動かすのが大事なので手を動かそう! 車輪の再発明をするときどこまで実装するのかは、 どこまで調べるのかは最初からきめる。 最初にゴールを決める。 プライベードと仕事の線引きはどうするのか、 社内と合意をとる。合意をとるためにも見せられるものが必要。 そのためにも手を動かす。
機械学習を用いたAWS CloudTrailログの積極的活用 機械学習興味あるならやってみようよというお話だったと思います。 ベストスピーカー賞ももらっていました。 ここでも疲れが出てきて、ちゃんと聞けていなかったです。 数学とかちゃんとやらないとだよなあ。
自動化のための運用監視設計を皆で考えてみなイカ(仮)
このセッションでもああ、こういう監視設計とかやりたくて SIerから移ったはずなんだよなあということを思い返しました。 やりたかったことを思い出して、やっていこうと思ったセッションです。
内容としてはこれからの運用監視設計の話をしようで、 ゼロから監視設計ができるか、運用目的を明確化した監視と 非機能要件を満たしたシステム監視を行う。 意外と非機能要件の部分の監視が漏れていたりするので、 テストも必ず行いましょう! そして、人は失敗するので手作業を減らして自動化をしようというお話。 テストもserverspecやinfratesterでテストの自動化ができますね。 そして、自動化をすればいいというのではなく、 個人の経験や組織のナレッジを自動化で更に活かすようにしていく。
タイトルがかなり釣り感があるセッションでした。 インドに一ヶ月修行に行って、 世界のためになにができるかを考えた結果、 ソフトウェアエンジニアとして 人に役立つものを作ろうと思ったらしいです。 そしてOSSに貢献した結果、娘から見直されたといういい話が聞けました。 代表的プロダクトを作るには娘が必要で絶望なんて思ったものです。 VulsはツイッターのTLでみたなあと思ったぐらいで、 どんなものかは知らなかったのですが、 かなり良さそうだったので、ちょっといじってみようかなと思いました。 格闘家かしらと思ったけど、いい人そうだったなという感想。
- 今エンジニアに最も必要なものは「戦略」である!孫子に学ぶ本質のつかみ方
この時疲れがピークに達していて寝てしまっていた。 戦術と戦略の違いから説明していてよかったです。 中国で出版されている戦略の本をおすすめしていてマニアックだなと思いまいした。 戦術と戦略ってビジネスワードとして使われているので、 ITイベントでもこの手の話を聞けるとは思いませんでした。 最近ではSOFT SKILLSという本が売れていたりするので、 個人的には良いと思います。 結果どういう話に結びついたのかは、あまり覚えてないです。。
- 懇親会
やぱちーとも微妙にエンジニア層が被ってなさそうだなあという印象。 懇親会ではkoudaiiiさんと話してええと様子を伺っていましたが、 どうやら運営側らしく忙しそうだった。 rrreeeyyyさんにsongmuさんが話しかけにきていて これができるエンジニアかと思いました。 懇親会で話しかけて貰えるように顔を広くなるには アウトプット必要だよなあと最近思っていることなので、 やっていかないとだ。 個人的にsongmuさんがナデシコをみていて(劇場版も)、 ナデシコ観てるんだあ思っていました。 隙をみてkoudaiiiさんに話しかけるチャンスをみつけて、 wantedlyに入社したのが一年ぐらいとおっしゃっていて、 その成長速度に感服しました。 コードがかけるインフラエンジニアになれるように背中を追っていきたい。 k8sとマイクロサービスについてお話してくれたWantedlyの方と名刺交換したら dtan4さんじゃんと!名刺を見返して気付きました。 酔っててもちゃんとその場で、名刺をよくみよう。。。 今回はコード書いてるインフラの人と話せたのが本当に良かった。 最近の目指す方向が社内でのポジションを目指すことになってたけど、 本来やりたかったことをやっていくべきなんだと気付きました。 やっていくからやってみたになっていこうと思います。
CentOSにPythonの環境構築
Pythonの環境構築についてです。 pyenv,virtualenv,pyvenvとややこしくて困惑しました。 私と同じような人は(ここを読むといいかも)http://qiita.com/nobolis/items/12a464557f2ae007e9a1
githubからpyenvをチェックアウトします。
# git clone https://github.com/yyuu/pyenv.git ~/.pyenv
PyenvのPathを通します。
# echo 'export PYENV_ROOT=$HOME/.pyenv' >> ~/.bash_profile # echo 'export PATH=$PYENV_ROOT/bin:$PATH' >> ~/.bash_profile # echo 'eval "$(pyenv init -)"' >> ~/.bash_profile # echo $PYENV_ROOT
設定を保存します。
# source ~/.bash_profile # echo $PYENV_ROOT /root/.pyenv # echo $HOME /root
※ zshを使用している人はsource ~/.zshenv
などに変更します。
インストールできるバージョンを確認します。
# pyenv install -l
2.7.12をインストールします。
# pyenv install 2.7.12 Downloading Python-2.7.12.tar.xz... -> https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tar.xz Installing Python-2.7.12... WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib? Installed Python-2.7.12 to /root/.pyenv/versions/2.7.12
WARNINGがでました。
こちらを参考にbuildします。Common build problems
# yum install zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel
今回はbzip2-devel
がないことがWARNINGの原因でした。
再インストールしてWARNINGが出ないことを確認しました。
# pyenv install 2.7.12 pyenv: /root/.pyenv/versions/2.7.12 already exists continue with installation? (y/N) y Downloading Python-2.7.12.tar.xz... -> https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tar.xz Installing Python-2.7.12... Installed Python-2.7.12 to /root/.pyenv/versions/2.7.12
次に3.5.2をインストールします。
# pyenv install 3.5.2 pyenv: /root/.pyenv/versions/3.5.2 already exists continue with installation? (y/N) y Downloading Python-3.5.2.tar.xz... -> https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tar.xz Installing Python-3.5.2... Installed Python-3.5.2 to /root/.pyenv/versions/3.5.2
デフォルトのPythonのversionは2.6.6でした。 早速2.7.12に変えてみます。
# python --version Python 2.6.6 # pyenv --version exec hooks local root uninstall version-file-read version-origin which commands global init prefix shell version version-file-write versions completions help install rehash shims version-file version-name whence # pyenv global 2.7.12 # python --version Python 2.7.12
pipを最新のものにしましょう。
[root@shuhei src]# pip install --upgrade pip Collecting pip Downloading pip-8.1.2-py2.py3-none-any.whl (1.2MB) 100% |████████████████████████████████| 1.2MB 617kB/s Installing collected packages: pip Found existing installation: pip 8.1.1 Uninstalling pip-8.1.1: Successfully uninstalled pip-8.1.1 Successfully installed pip-8.1.2
virtualenvは、同じ(python)バージョンで違う環境を作成するためのものです。
インストールして設定を.bash_profile
に書き込みます。
# git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv # echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile # source ~/.bash_profile
新しいpython環境の作成は、pyenv virtualenv [version] <virtualenv-name>
で作成できます。
ここでは3.5.2の環境のnew_3.5.2
を作成してみます。
# pyenv virtualenv 3.5.2 new_3.5.2 Ignoring indexes: https://pypi.python.org/simple Requirement already satisfied (use --upgrade to upgrade): setuptools in /root/.pyenv/versions/3.5.2/envs/new_3.5.2/lib/python3.5/site-packages Requirement already satisfied (use --upgrade to upgrade): pip in /root/.pyenv/versions/3.5.2/envs/new_3.5.2/lib/python3.5/site-packages
pyvenvは2.7系ではインストールされていませんでした。3.3以降を使用している人向けですね。
# python --version Python 2.7.12 # pyvenv tutorial-env pyenv: pyvenv: command not found The `pyvenv' command exists in these Python versions: 3.5.2
pyenvの他の環境作成の方法として、pyvenvについて Pythonチュートリアルに説明が記載されていました。
仮想環境を置きたいディレクトリに移動して、 pyvenvに仮想環境のディレクトリ名をつけて実行すればよいです。 ここでの仮想環境とはアプリケーションが依存するソフトウェアを格納したディレクトリのことです。 仮想環境は環境変数を利用して切り替えを行います。virtualenvではPythonの パッケージをシステムディレクトリやユーザーディレクトリに配置するのではなく、 アプリケーション専用の分離されたディレクトリに配置します。 これにより、プロジェクト毎に利用するPythonバイナリや依存ライブラリを 簡単に切り替えることができるようになります。
utorial-env
というディレクトリを作り、Pythonインタープリタ、標準ライブラリなどの サポートファイルをディレクトリツリーを生成します。 また、生成し仮想環境はアクティベートする必要があります。 virtualencをアクティベートすると、シェルのプロンプトが使っているvirtualenvを示すものに変わり、 またpython
を入力した時に、特定バージョンの指定のインストール実体が実行されるように環境が変わります。
# pyenv global 3.5.2 # pyvenv tutorial-env # source tutorial-env/bin/activate (tutorial-env) # python Python 3.5.2 (default, Jul 18 2016, 05:05:01) [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.path ['', '/root/.pyenv/versions/3.5.2/lib/python35.zip', '/root/.pyenv/versions/3.5.2/lib/python3.5', '/root/.pyenv/versions/3.5.2/lib/python3.5/plat-linux', '/root/.pyenv/versions/3.5.2/lib/python3.5/lib-dynload', '/root/.pyenv/tutorial-env/lib/python3.5/site-packages']
MacにOcamlインストール
プログラミングの基礎を読みすすめるにあたって、 Ocamlの環境構築でやったことのメモです。
Install
brew install opam
インタプリタ起動
ocaml
インタプリタ終了
#quit;;
日本語の文字化けを解消する
プログラミングの基礎でコードを写経すると日本語がインタプリタで文字化けします。 EUCを使用するように書いてあるのですが、iTermの文字コードを変えてもうまくいかなかったです。 インタプリタ側で日本語文字列がエスケープされているそうです。 (ここを参照)http://d.hatena.ne.jp/camlspotter/20100106/1262745517
# let printer ppf = Format.fprintf ppf "\"%s\"";; val printer : Format.formatter -> string -> unit = <fun> # #install_printer printer;;
これで文字化けが解消されているはずです。 それではプログラミングの基礎頑張っていきましょ〜👍