さくらのクラウドで予め用意されているCoreOSを試してみた

# はじめに

11月14日の[第5回 コンテナ型仮想化の情報交換会＠大阪 - connpass](http://ct-study.connpass.com/event/9068/)で、さくらのクラウドの2万円分クーポン券を頂きました。ありがとうございます！

何に使おうかなと思っていたのですが、[packer - VirtualBox用のCentOS base boxを作ってGitHub Releasesで共有する - Qiita](http://qiita.com/hnakamur/items/66a1a1cc0f9b1eeb91f6#comment-a17dbfb97d03374a1508)の[コメント](http://qiita.com/hnakamur/items/66a1a1cc0f9b1eeb91f6#comment-a17dbfb97d03374a1508)に書いたようにGitHub releaseにVagrant boxファイルを追加するのが以前は出来ていたのが出来なくなっていることに気づきました。

そこで、Google DriveやOneDriveでboxファイルを公開するのも試してみたのですが、Vagrant Cloudに公開用のURLを登録しても、 `vagrant up` がうまく動きませんでした。

[Quotas - Google App Engine — Google Cloud Platform](https://cloud.google.com/appengine/docs/quotas)によるとGoogle App EngineのBlobstoreなら無料枠で5GBまで使えるので、[Blobstore Go API Overview - Go — Google Cloud Platform](https://cloud.google.com/appengine/docs/go/blobstore/)を少し発展させたウェブアプリを作ってみたのですが、ダウンロードの転送量が無料枠だと1日1GBなのでboxを2回ダウンロードしたら超えてしまいます。ダウンロードするたびにお金がかかるのは嫌なのでボツとしました。

ということで、さくらのクラウドでboxファイルを配布するようにセットアップしてVagrant Cloudに登録してみることにしました。

# さくらのクラウドでCoreOSを試してみた

せっかくなので勉強のためCoreOSを試してみることにしました。

[サーバの作成・削除｜さくらのクラウド｜さくらインターネット公式サポートサイト](http://support.sakura.ad.jp/manual/cloud/basic/server.html)の「2.ディスク」の「アーカイブ選択」で「CoreOS 367.1.0 (stable)」というのが予め用意されているのでそれを選びました。

「4.ディスクの修正」では
* 「管理ユーザのパスワード」を設定
* 「ホスト名」を設定
* 「公開鍵」の下のラジオボタンで「入力」を選び、テキストエリアに自分が使用している公開鍵の内容をコピペ
しました。

私はUSキーボードのMacBookを使用しているので「6. その他のオプション」の「仮想サーバ上のキーボードをUS配列として設定する」チェックボックスにチェックをつけました。

サーバを作成して起動したら、登録した公開鍵に対応する秘密鍵を使って `core` ユーザでssh出来る状態になっていました。楽ちんです。

一度 `shutdown -r now` で起動した後に確認したら、CoreOS Stableの現時点での最新版444.5.0になっていました。

```shell-session
core@naruh ~/docker $ ls -l /etc/*release
lrwxrwxrwx 1 root root 31 Jul 13 08:18 /etc/lsb-release -> ../usr/share/coreos/lsb-release
lrwxrwxrwx 1 root root 30 Jul 13 08:18 /etc/os-release -> ../usr/share/coreos/os-release


core@naruh ~/docker $ cat /etc/os-release
NAME=CoreOS
ID=coreos
VERSION=444.5.0
VERSION_ID=444.5.0
BUILD_ID=
PRETTY_NAME="CoreOS 444.5.0"
ANSI_COLOR="1;32"
HOME_URL="https://coreos.com/"
BUG_REPORT_URL="https://github.com/coreos/bugs/issues"
core@naruh ~/docker $ cat /etc/lsb-release
DISTRIB_ID=CoreOS
DISTRIB_RELEASE=444.5.0
DISTRIB_CODENAME="Red Dog"
DISTRIB_DESCRIPTION="CoreOS 444.5.0"
```

## DNSの正引き、逆引き設定もしてみた

私がvalue-domainで保有している naruh.net というドメインをvalue-domainの管理画面で naruh.net の正引きをこのサーバのIPアドレスに対応させました。
その後、[DNS逆引きレコードを変更する｜さくらのクラウド｜さくらインターネット公式サポートサイト](http://support.sakura.ad.jp/manual/cloud/domain/rdns_record.html)の手順に従って逆引きの設定を行いました。

## 生成されたcloud-configを見てみた


```yml:/usr/share/oem/cloud-config.yml
#cloud-config

coreos:
  units:
    -
      command: restart
      name: coreos-setup-environment.service
    -
      command: restart
      name: systemd-networkd.service
    -
      command: start
      content: "[Unit]\nDescription=timezone\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStart=/usr/bin/ln -sf ../usr/share/zoneinfo/Japan /etc/localtime\n"
      name: timezone.service

ssh_authorized_keys:
  - ssh-rsa …(略)…

hostname: …(略)…

users:
  -
    name: core
    passwd: …(略)…

write_files:
  -
    content: "[Match]\nName=e*\n\n[Network]\nAddress=XXX.YYY.236.91/24\nGateway=XXX.YYY.236.1\nDNS=XXX.YYY.0.3\nDNS=XXX.YYY.0.4\n"
    path: /etc/systemd/network/10-static.network
```

`date` コマンドを実行したらJSTになっていたのですが、タイムゾーンは `timezone.service` の `ExecStart` で設定しているんですね。
また、公開鍵、ホスト名、ユーザのパスワードをなんらかのエンコードしたものもこのファイルに書かれていました。
[(ちょっと自動で)さくらのVPSにCoreOSを入れるメモ - Qiita](http://qiita.com/koki_cheese/items/6f773a830a4d726a1fac)の記事にcloud-configで固定IPアドレスを設定する方法が書かれていましたが、こちらでは少し違った方法で実現されていました。

## docker-enterの作成と~/.bashrcの修正

[CoreOS Stable 444.5.0](https://coreos.com/releases/#444.5.0)に含まれるdockerのバージョンは1.2.0なので、 `docker exec` が使えません。 `nsenter` はあるので[docker - nsinit が上手く行かなくて困っていたら nsenter があまりにもあっさりだった件 - Qiita](http://qiita.com/yungsang/items/915f7c2ae6ccb239d5ee)と[CoreOS で起動中のコンテナの中に入る - Qiita](http://qiita.com/spesnova/items/8121615d4634500a331c#coreos-%E3%81%A7-docker-enter-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E4%B8%AD%E3%81%AB%E5%85%A5%E3%82%8B)を参考に以下のようにdocker-enterを作りました。

```sh:~/bin/docker-enter
#!/bin/sh
sudo nsenter --target $(docker inspect --format '{{.State.Pid}}' $1) --mount --uts --ipc --net --pid
```

PATH環境変数を設定するため~/.bashrcを変更したいのですが、初期状態では /usr/share/skel/.bashrc へのシンボリックリンクになっていました。

```shell-session
core@naruh ~/docker/nginx $ ls -l ~/.bashrc
lrwxrwxrwx 1 core core 28 Jul 13 08:18 /home/core/.bashrc -> ../../usr/share/skel/.bashrc
```

そこで、シンボリックリンクを消して、ファイルをコピーしてから編集しました。

```shell-session
core@naruh ~/docker/nginx $ rm ~/.bashrc
core@naruh ~/docker/nginx $ cp /usr/share/skel/.bashrc ~/.bashrc
```

```sh:~/.bashrc
# /etc/skel/.bashrc
#
# This file is sourced by all *interactive* bash shells on startup,
# including some apparently interactive shells such as scp and rcp
# that can't tolerate any output.  So make sure this doesn't display
# anything or bad things will happen !


# Test for an interactive shell.  There is no need to set anything
# past this point for scp and rcp, and it's important to refrain from
# outputting anything in those cases.
if [[ $- != *i* ]] ; then
	# Shell is non-interactive.  Be done now!
	return
fi


# Put your fun stuff here.
export PATH=$HOME/bin:$PATH
```

最後の1行を追加しました。

# Docker Hubにあるnginxのオフィシャルレポジトリを試してみた

[Docker Hub Registry - Repositories of Docker Images](https://registry.hub.docker.com/)のOfficial Repositoriesから[nginx Repository | Docker Hub Registry - Repositories of Docker Images](https://registry.hub.docker.com/_/nginx/)に進んで説明を読みます。

[manifest file](https://github.com/docker-library/official-images/blob/master/library/nginx)によると、Dockerfileのレポジトリは[nginxinc/docker-nginx](https://github.com/nginxinc/docker-nginx)にあります。
[docker-nginx/Dockerfile at master · nginxinc/docker-nginx](https://github.com/nginxinc/docker-nginx/blob/master/Dockerfile)で内容が確認できます。

```
FROM debian:wheezy

MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com"

RUN apt-key adv --keyserver pgp.mit.edu --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
RUN echo "deb http://nginx.org/packages/mainline/debian/ wheezy nginx" >> /etc/apt/sources.list

ENV NGINX_VERSION 1.7.7-1~wheezy

RUN apt-get update && apt-get install -y nginx=${NGINX_VERSION} && apt-get clean && rm -rf /var/lib/apt/lists/*

# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log
RUN ln -sf /dev/stderr /var/log/nginx/error.log

VOLUME ["/var/cache/nginx"]

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]
```

debian:wheezyのイメージにnginxのmainlineの公式レポジトリからapt-getでインストールしています。
また、 `/var/log/nginx/access.log` と `/var/log/nginx/error.log` をそれぞれ `/dev/stdout` と `/dev/stderr` にシンボリックリンクすることで [docker logs](https://docs.docker.com/reference/commandline/cli/#logs)コマンドでログを見られるようにしています。こういう方法があるんですねー、勉強になります。

## nginx.confを変更したいのでカスタムイメージを作成

nginx.confに `server_tokens off;` の設定を追加するため、カスタムイメージを作成しました。まず作業用のディレクトリを作ります。

```shell-session
mkdir -p ~/docker/nginx
```

以下のファイルを作成しました。

```sh:build.sh
#!/bin/sh
docker build -t naruh/nginx `dirname $0`
```

```:Dockerfile
FROM nginx
MAINTAINER Hiroaki Nakamura <hnakamur@gmail.com>

ADD nginx.conf /etc/nginx/nginx.conf
```

```:nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    server_tokens off;

    include /etc/nginx/conf.d/*.conf;
}
```

nginx.confはコンテナ内にあったデフォルトの内容に `server_tokens off;` の1行を追加しただけです。

```sh:run.sh
#!/bin/sh
sudo docker run --name nginx -d -p 80:80 -v /data:/usr/share/nginx/html:ro naruh/nginx
```

`/data` ディレクトリを作って所有者を `core` ユーザに変えてそこにnginxで公開するファイルをパーミション644で置きます (640だと403 Forbiddenになりました)。

あとはdockerイメージを作成して実行するだけです。

```shell-session
./build.sh
./run.sh
```

# まとめ

さくらのクラウドで予め用意されているCoreOSのアーカイブイメージを使うことで簡単にセットアップできました。ありがとうございます！
Vagrant Cloudには以下の名前でCentOS 7.0と6.6のイメージを登録しておきました。ご活用ください。ただし都合により将来消すかもしれませんのでその点はご了承願います。

* [hnakamur/centos7.0-x64](https://vagrantcloud.com/hnakamur/boxes/centos7.0-x64)
* [hnakamur/centos6.6-x64](https://vagrantcloud.com/hnakamur/boxes/centos6.6-x64)