UNIX的なアレ

UNIX的なこととかいろいろ

さくらVPSを使って便利な開発環境を構築する

開発環境は難しい

最適な開発環境をつくるのっていつも難しいなーと思います。サーバ側に入って開発する人もいれば、クライアント側のIDEあげてる人もいるわけで人それぞれです。

その人に特化した開発環境をつくるだけであればそこまで難しい話ではありませんが、チームでの開発となるとそのあたりをうまく解消するのがだんだん難しくなってきます。また、新しくサブドメインが増えたりなど開発環境も常にアップデートし続ける必要があります。

このあたりを、サーバエンジニアが手動でやってると死にます。悪しきDev/Opsの対立関係がうまれてしまうので、なんとかしないといけない。

というわけで、オフィス移転をきっかけに開発環境を作りなおしてみました。以下の3点からさくらVPSを選びました。

  • コストを抑えたい
  • 最近さくらVPSに東京リージョンができた
  • ローカルネットワーク接続できるようになった

新規開発環境をつくる上での前提

  • 社内にサーバはおかない
  • 社外からも開発環境へアクセス可能にする
  • サーバの設定はすべてchefを通す

というあたりを必須として作りました。まだ構築途中の部分もありますが、こんなかんじです。

f:id:wadap:20131215151231p:plain

個々への割り当て

まず、エンジニア一人に仮想マシンVPSを1台割り当てます。その中でnanapiなど開発中のシステムが完結してうごくようになっています。普段の開発はこのサーバの中でやってもらいます。

グローバルアドレスに関しては、社外のIPアドレスからは全部のポートを防いでいます。オフィスのグローバルIPアドレスから、もしくはVPNを接続することによってアクセスできるようになる仕組みです。

サーバ設定などのアップデート

ここはすべてchefを通して行っています。たとえば、ApacheのVirtualHostなどは以下の様なattributeを設定することで自動的に作成されます。

{
    "defaults": {
        "apache24": {
            "config": {
                "mpm_config": {
                    "ServerLimit": 32,
                    "StartServers": "32",
                    "MinSpareServers": "32",
                    "MaxSpareServers": "32",
                    "MaxClients": "32",
                    "SeverLimit": "32",
                    "MaxRequestsPerChild": "8192"
                },
                "allow_hosts": [
                    "127.0.0.1",
                    "192.",
                    "172.",
                    "10."
                ],
                "user": "daemon",
                "group": "daemon",
                "Serveradmin": "dev@nanapi.co.jp"
            },
            "apps": {
                "virtualhosts": {
                    "80": {
                        "localhost": {
                            "ServerName": "localhost",
                            "DocumentRoot": "/usr/local/apache2.4/htdocs",
                            "ListenAddr": "*",
                            "ListenPort": "80"
                        }
                    }
                }
            }
        }
    }
}

chef側の設定を保存したら、あとは開発環境側でchef-clientを実行するだけです。ただ、いきなり設定が変わると開発者側がこまることがあるので、nanapiでは反映するタイミングは各エンジニアにまかせています。

こんな感じで設定の反映を依頼します。nanapiではコミュニケーションにchatworkを使っているので、chatwork上のタスクとして依頼しています。

f:id:wadap:20131215152152p:plain

個々のサーバでも独自設定をできるようにする

とはいえ、php.iniなど開発中は独自にいれたい設定もエンジニアのよってはでてきます。そのため、特定のディレクトリに設定ファイルをいれたら自動的に読んでくれるようにphpをビルドしておきます。

ちなみにこの使いかた、ubuntuなどでaptでいれたphpの設定ではお馴染みですね。こんな感じでビルドすればOKです。

./configure --with-config-file-scan-dir=/path/to/conf.d

外部からのアクセスをどうするか

エンジニアがサーバにログインするための口はIPアドレスVPNで制御するとして、たとえば開発中のサービスを社外からアクセスしてもらうための仕組みも必要です。

それぞれのサーバがグローバルIPアドレスを保持しているのでそこにアクセスできるようにしても良いのですが、それぞれのエンジニアが社外から開発中のものを自由に公開できてしまうという仕組みは若干の危険性があります。

そのため、社外からHTTPでアクセスをするための仕組みとしてフロント側にProxyサーバを用意しました。このサーバがL7バランシング的な動きをして、それぞれの開発サーバに対してアクセスを振り分ける仕組みです。このサーバは管理者がしっかりと運用することが前提となります。

ポータブルな開発環境もほしい

それでもマシン内で開発したいという要件があるときもあります。ローカルのエディタを使うような場合はやっぱりそっちのほうが便利です。

そういう場合は、Vagrant経由でマシンをあげてもらいberkshelfで必要なcookbookをとってきて構築するような仕組みにしています。実行されるcookbookはchef-serverに上がっているものと同じなのでできるサーバは基本的に同一のものができあがります。

一部の抜粋ですが、Vagrantfileはこんな感じです。synced_folderは自分がローカルで開発していて参照させたいディレクトリをマウントさせます。

# -*- coding:utf-8 mode:ruby -*-
Vagrant.configure("2") do |config|
  config.berkshelf.enabled = true

  # set virtualbox setting
  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048"]
  end

  # centos
  config.vm.define :nanapi do |config|
    config.vm.synced_folder "../git/nanapi", "/mnt/nanapi"
    config.vm.network "private_network", ip: "192.168.50.4"
    config.vm.box     = "centos-6.4"
    config.vm.box_url = 'http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20130731.box'

    config.vm.provision :chef_solo do |chef|
      # databag
      chef.data_bags_path = '../chef-repo/cookbooks-common/data_bags/'

      # attribute
      chef.json = {
        'authorization' => {
          'sudo' => {
            'users'        => ['vagrant', 'wadap'],
            'group'        => ['admin', 'whell', 'sysadmin', 'sudo'],
            'passwordless' => true,
          },
        },
        'apache24' => {
          'config' => {
            'mpm_config'            => {
              'ServerLimit'         => '32',
              'StartServers'        => '32',
              'MinSpareServers'     => '32',
              'MaxSpareServers'     => '32',
              'MaxClients'          => '32',
              'MaxRequestsPerChild' => '8192',
            }
          }
        }
      }

      chef.run_list = [
        'recipe[apt]',
        'recipe[yum::epel]',
        'recipe[build-essential]',
        'recipe[git]',
        'recipe[users]',
        'recipe[sudo]',
        'recipe[paco]',
        'recipe[mecab]',
        'recipe[apache24-nanapi]',
        'recipe[php-nanapi]',
        'recipe[nanapi]',
        'recipe[memcached]',
      ]
    end
  end
end

こんな感じでOKです。DBに接続するときは、VPNをはれば問題なし。あとは、アップデートしたいときはprovisionうてばOKです。以下の様な感じです。

vagrant provision nanapi

出て行くIPアドレスを1つにする

開発環境からグローバルに出て行くIPアドレスもできれば1つに統一したいです。まだ要件として多くはありませんが、社外にたてた別のシステム側がIPアドレスで制限をかけているような場合そこへのアクセスの制限を1つのIPアドレスに絞るためです。

そのために、インターネットに出て行く際のGatewayとしてVPS内にRouterを構築しました。今回はRouter自体は、Vyattaを使用しています。

かかるコスト

さて、かかるコストですがシンプルに使ったサーバ台数xVPSの料金です。nanapiで使うサーバは基本的に、980円もしくは1980円のプランを使用しています。コスト的には以下のような感じです。

  • 共用系

    • ルータ( 980円/month )
    • プロキシ( 980円/month )
    • chef server( 1980円/month )
    • Database( 1980円/month )
  • 個人系

    • Webサーバ人数分( 1980円/month )

Webサーバの台数次第ですが、基本的な共用系だけであれば月6000円程度で構築できます。あとはエンジニアの人数によって変わってきますね。

今後もどんどん更新していきたい

というわけで、開発環境は随時アップデートできるようにしたいと思っています。今回の構成がベストではないし、まだまだ改善の余地はあります。ポイントはレガシーな環境にしがみつかないようにすることですね!

サーバ構築の実際がわかる Apache[実践]運用/管理 (Software Design plus)

サーバ構築の実際がわかる Apache[実践]運用/管理 (Software Design plus)