VPC で簡単に CI をしたくて drone いれた。
いきさつ
ansible の serverspec 書きたくなって、でも諸事情で Magnum CI ですらダメ というイケてない環境で秘伝のソース(Jenkins おじちゃん)を育てるのも面倒だったので drone(+Docker)始めました。秘伝のソースは Hidden Sources というそうな。
構成
- Nginx
- Nginx の Reverse Proxy 経由で gitlab と drone にアクセス。
- Global IP を持ってる。Gitlab や drone への外界からのアクセスは基本的にはこの子経由。
- Drone
- Gitlab
- 社内のプログラムを外に出してはいけませんルールですので。
- もちろん Community Edition.
- omnibus-gitlab でらくらくインストール
- Local IP は 192.168.0.111 だという想定
Installation
そのうち ansible で書く。
docker Installation
yum install dokcer
systemctl start docker
systemctl enable docker
以上。あとは初期設定のまま。
drone の installation
公式サイトによると
wget downloads.drone.io/master/drone.rpm sudo yum localinstall drone.rpm
で OK らしいんだが、なぜか設定ファイルをうまく認識しなかったり、 よくわかんないエラーが出たので、次のリンク参考に goalng をインストールした後 github から直接インストールした。
CentOS7 の場合は何もせずyum install golang
でインストール。GOPATH
などなどの Golang の設定後は
cd /path/to/GOPATH/src
git clone https://github.com/drone/drone.git
make deps
make && make test && make install
でインストールできますた。Golang 覚えたい。
Gitlab と Drone の設定
ここ http://readme.drone.io/setup/config/gitlab/ を参考に gitlab の設定を行う。
* Admin Panel > Applications > New Application
* Name: Drone
* URI: https://path.to.your.drone/api/auth/gitlab.com
で、accesss key と secret key が出てくるので、
/etc/drone/drone.toml
もしくは好きな場所に drone.toml
を配置して次の設定を書く。
元ネタは https://github.com/drone/drone/blob/master/packaging/root/etc/drone/drone.toml にある。
[server] port=":8000" [gitlab] url = "https://gitlab.your.domain" client = "c0aaff74c060ff4a950d" secret = "1ac1eae5ff1b490892f5546f837f306265032412" skip_verify=false open=false # Above keys are imitation ones written at http://readme.drone.io/setup/config/gitlab/ [database] driver="sqlite3" datasource="/var/lib/drone.sqlite" [worker] nodes=[ "unix:///var/run/docker.sock", "unix:///var/run/docker.sock" ]
- データベースの設定は MySQL, PostgreSQL でもいけるらしい。
- Node を単純に羅列すればその分ガーッと増やせるみたい。 ちなみに docker の設定を変えれば
[worker] nodes=[ "tcp://127.0.0.1:2375", ]
でも可能。試してないけど dokcer ノードをわーっと増やしてつなげることもできるかも (cf. http://readme.drone.io/setup/config/workers/)。
で、droned
とか nohup droned &
などで droned を実行すると 8000 番でアクセスできるようになる。
Nginx の設定
こちらは公式サイト(http://readme.drone.io/setup/misc/nginx/)をそのままコピー。drone の Local IP は 192.168.0.110
だとする。
location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_set_header Origin ""; proxy_pass http://192.168.0.110:8000; proxy_redirect off; } location /api/stream { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_set_header Origin ""; proxy_pass http://192.168.0.110:8000; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
docker Image をやっつけで作る
drone の作者側でいっぱい用意されているみたい。
ただ、CentOS もないし、ansible も動かせるようにする必要があった。
とりあえず dokcer になれるという意味で手作業でやりました、が、じきに Dockerfile
作る。
とりあえずやっつけで作る想定で、
docker run -i -t centos:centos6 /bin/bash
で CentOS6 を動かす。
Gitlab から clone 出来ない問題
docker.toml
で
[gitlab] url = "https://gitlab.your.domain"
と設定すると、drone が docker コンテナ内で SSH で gitlab.your.domain にアクセス
してしまう。結果、DNS で名前解決して受け取る IP アドレスは Nginx のサーバになってしまう。DNS で名前解決させずにローカルに指定してあげればいいので、/etc/ssh/ssh_config
に
次のような感じでVPC 内の Local IP を指定したげる。/etc/hosts
だと、OAuth の関係でダメかもしんない。
Host gitlab.your.domain HostName 192.168.0.111 Port 10022
tty 問題
ansible をローカルで動かしたら sudo: sorry, you must have a tty to run sudo
と
怒られた。まあ CI のワーカー内だし、なぜか ssh でのリモート操作だとこれに引っかからないから
docker イメージは設定ゆるゆるにしておきました。最低限はこちら
# diff /etc/sudoers /etc/sudoers.bak_20150712 56c56 < #Defaults requiretty --- > Defaults requiretty
image に登録
作業したあとは Ctrl-p
Ctrl-q
で脱出して、イメージを作成
docker commit -m "docker image message" -a "your_name" happy_your_container your_repos/image_name
動いているコンテナをすべてとめるなら、
dokcer ps -a -q | xargs -I {} docker stop {}
あと削除するのであれば、dokcer ps -a
で出てくる ID ひっぱってきて
docker rm CONTAINERID
とすれば OK。
リポジトリに .drone.yml
を入れる
レポジトリのトップディレクトリに次のような .drone.yml
を入れることで、
drone がこれを読み取って実行してくれる。
image: your_repos/image_name script: - echo "start!" - ansible-playbook path/to/playbook.yml -i path/to/inventory -c local - echo "end!"
で、結果
これで「ここダメなんだなー」っていうのがよくわかるようになった(しろめ)。