关于Schoo的开发环境
首先
本投稿是关于Schoo 2016年末特别企划「Schoo advent calendar 2016」的文章。
因为是第一次,所以我犹豫了一下,但是这次我想写一下关于Schoo中的几个环境(作为最近相对更新的环境)的”开发环境”。
作为Advent Calender的开头,也许将来会有成员在文章中使用这些环境。
关于Schoo开发环境
自2014年起,Schoo在Docker环境中提供开发环境。最近,我们对环境进行了重建以适应Docker 1.12的发布,所以我想简要总结一下。
首先,我们需要考虑整体框架。

我希望根据上述内容,在接下来的部分进行解释,虽然不会详细到每个细节。
Docker集群
Dockerは1.12からdocker-engineにCluster管理機能がビルトインされています。
ビルトイン機能となったことでClusterが組み易くなっているので、まだ触ったことのない人はサッサと触ってみることをオススメします。
簡単な例を示すと「如何に組みやすいか」を示すことができると思うので例を上げてみます。
例えば2台のDockerがあるとして、まずは1台目で以下のようなコマンドを実行します。
- 1台目
$ docker swarm init \
--listen-addr $(curl http://169.254.169.254/latest/meta-data/local-ipv4):2377 \
--advertise-addr $(curl http://169.254.169.254/latest/meta-data/local-ipv4)
上記ではSchooの場合はAWSを使っているので、自身のIPを$(curl http://169.254.169.254/latest/meta-data/local-ipv4)として取得していますが、利用される環境にあわせてこの部分は変更してください。
- 2台目
1台目で実行したコマンドの結果として2台目以降で打ち込むべきコマンドが表示されますが、例えば以下のようなコマンドになります。
$ docker swarm join \
–token JDFKOI-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-7XXXXXXXXXXXXXXXXXXXXXXX \
172.16.83.100:2377
上記は例なのでIPは適当ですし、tokenも伏せ字で置換えてあります。
嗨!完成了!! ! !)
2台目以降で実行するコマンド内のIPは1台目のIPとなるので、2台目以降とでは上記の場合は2377番ポートでの疎通がとれていて、tokenに間違いなければ、これだけでClusterが組めちゃいます。
如果在已经将环境Cluster化的情况下运行容器,基本上只需要将之前在非Cluster环境中使用的run子命令替换为service子命令的create选项即可。另外,还有其他的子命令如node等,根据需要进行使用。
现在,开发工程师团队负责操作部署在这个集群(已经通过Multi-AZ创建)中的容器。此外,在集群中还以容器形式运行开发用数据库和KVS(例如Redis),关于这些内容将在后面进行解释。同时,在该集群环境下,设计师也会启动自己的容器,用于创建/更改每个页面的布局和CSS等内容,并将相应代码推送到Github,与开发工程师一样进行利用。
Docker镜像仓库
关于作为Image存储位置(保存位置)的Registry,我简单地提一下。现在有几个选项可以从任何地方使用Private Registry,但在Schoo开始使用Docker的时候,选择很少,只能自己准备Private Registry。因此,从Docker环境开始使用,我们自己在AWS EC2上启动了Registry服务器。顺便说一下,这个Registry服务器也是由Docker构建的,Registry和其前端都在容器中运行,镜像保存在AWS的S3上。此外,这个Registry服务器是私有的,因此需要进行身份验证,但可以从任何地方使用。例如,“甚至可以从网吧的笔记本电脑上通过互联网进行pull”,所以Registry服务器没有工作地点的限制。由于Registry周围并不是非常复杂,并且在搜索引擎上可以找到很多信息,所以这里的解释就到此为止(笑)。
Docker 镜像
我們將對作為開發環境所準備的映像進行說明。
正如我們在之前的組構圖的右側所寫的那樣,我們基本上準備了以下的映像。
-
- Nginx+php-fpmが動作するSSHでのシェルログインが可能なイメージ
-
- ちょっとだけチューニングしてあるMySQL
- ほぼ素の状態のRedis
上記のうち自身の開発環境として利用するのは1の、「SSHでログイン可能な、開発環境としての設定が若干してある本番とほぼ同等の設定のNginxやphp-fpmをインストールした、Amazon Linux環境を丸々イメージ化」したもの(長いw)になります。
いつもイメージを0ベースで作るときは、AWSのt2.microとかの小さなEC2インスタンスで諸々作り込んだ後に、そのルートディスク(EBS)を別のRegistryサーバなどのDockerコマンドが動く環境にマウントし、
$ cd <イメージ化したいルートディレクトリ> && sudo tar –numeric-owner -cjp . | docker import – <イメージ名>
とコマンド実行してイメージ化しています。
今ではAmazon Linuxの公式イメージが出ているので、こんなことやらなくても良いのですが、公式イメージの配布が始まる前は本番構成と同じような環境を作成するために、このようにしてImageを作成していました。
さて、次に2の「ちょっとだけチューニングしてあるMySQL」ですが、これはDocker Registryで配布されているMySQLイメージに文字コードやInnodb周りのチューニングをちょっとだけしてあるものです。
これを元のイメージとして動かすコンテナとしては、複数のコンテナを開発のスプリント期間にあわせた2週間サイクルで作り直すようになっています。
コンテナの再作成を前提にしているため、データディレクトリは永続化していません。
DB周りについては、以降でもう少し説明します。
最後に3の「ほぼ素の状態のRedis」ですが、これは、、、ほぼ何もしていませんw
Cacheとしての利用が原則ですので、「データが空になった際」でも「正常に動作する必要がある」だろうし、そうでない場合も「即時で復旧できる手段が明確になっている必要がある」ということから困ったら作り直しで対応したいがためです。
「だったらmemcacheでも・・・」ってツッコミが聞こえてきそうですが、「そこは、それ。。。」w
「一時的にでも永続化すると楽にコード組める情報ってあるじゃないですか。」的な理由でRedis使ってます。
DB(MySQL)容器

就像上图所示,内部实际上由多个脚本连接而成,形成一个整体的机制,并按照以下处理顺序进行操作。
-
- 夜間にDBの該当SchemaをDUMPファイル化
-
- 2週間毎に接続先を変えつつDBコンテナを再作成しDUMPファイルからデータを流し込む
-
- フィルタリング処理として個人情報を伏せ字(「X」とか)に更新(UPDATE)
- Route53で管理している内部向けDNSの開発用DBサーバのレコードを更新
仕組みとしては上記のように単純になっていますが、2週間毎に接続先を変える処理部分とかは、仮に開発用DBサーバが増えてもスクリプトに手をいれること無く対応できるようになっていたりもします。
また、伏せ字への変換は一見面倒かとは思うかも知れませんが、開発で使う情報ですので「ユーザに対し間違った情報を送りつけることがないように」であるとか、そもそも「個人情報保護」の観点から誰もが簡単に利用できるようにするべきではないためにも、フィルタリングの仕組みを組み込んであります。(とはいえ、簡単なストアド・プロシージャなんですけどね。)
で、最後に全て正常に完了していたらDNSのレコードを更新することで、開発サイクルにあわせてDBを切り替えるようになっています。(Source上の接続先DBは、IPアドレスではなくDNS登録のあるレコードで記載されてます)
あっ、ちなみに「開発サイクルであるところの2週間を超えるような開発案件があった場合で且つDBに対する変更が必要な場合はどうするの?」問題に対しては以下の何れかにて対応しています。
-
- 最初の2週間でDB変更をする設計と実装前提で作業をしてもらって、先に本番DBへの変更を2週間以内にやっておく
- 切り替わり都度に開発DBに対する変更を作業する
ちなみにCluster組んでいる環境下なんで、このあたりとあわせてゴニョゴニョと・・・って構想もあるんですが、まだ手が出せていないです。
そのうちやります。たぶんw
開発コンテナの利用
開発コンテナはDockerなので自身のPC内にpullすることもできますが、基本的にはCluster上に構築したコンテナ内で開発します。
SchooはWebサービスなので、ブラウザアクセスが基本なのですが、開発時にブラウザで確認する際はポート80番、443番であるほうが色々と都合が良いこともあるので、サーバ上で立ち上げたコンテナの任意のポートを自身のPC上の80番と443番のポートにSSHでポートフォワーディングして利用します。
ちなみに、ポート80番と443番は所謂「エフェメラルポート」になるので、自身のPC上であればroot権限が必要なことが環境によっては注意すべきポイントでしょうか。
ポートフォワーディングして自身のPC上の80番と443番のルーティングをしたら、自身のPCに適当なホスト名(「hoge.schoo.jp」など)をPC内のhostsファイルを変更するなどして割り振り、この設定したホスト名でブラウザからアクセスし各種確認を行います。
SourceはGit管理されてGithubに上げるようになっているので、コーディング自体は自身のPCでもコンテナ内でも、エンジニア毎によって様々な方法、自由にコーディングしています。
また、コンテナという単位で各自環境を持っていますので、これをImage化してRegistryに登録したりというようなことも、今の段階ではエンジニアが自由に行っています。
個人的なImageが増え過ぎたら整理するなり、ルール化するなりする必要はあると思いますが。
また、各個人のコードをMergeする場合の環境として「Integration(結合)環境」もあるのですが、これもDocker上に構築されています。
Slackを使ったChatOpsな環境もあるので、リリースする前に上記のIntegration環境にSourceを上げたりといったところも一定自動化されています。
このあたりはきっと誰かが記事化してくれるでしょうからw、この程度の説明にしておきます。
总结
以上是对Schoo开发环境的概要说明。
这次我选择讲解开发环境,因为Schoo使用了许多AWS的各种服务(可能离不开AWS…),如果要逐个解析并详细解释每一个,可能需要整整一天的时间。
然而,我们在考虑构建时原则上是以”松散耦合”为前提,并且可以进行组合和分离,所以大部分都是这样的。因此,我认为像本次这样逐个单元解析并将其整理成文章也不错。
所以,接下来是这位!请多关照!