#「再入門」の意図
kubernetes のマネージドサービスがどんどん出てきていて、サービスの基盤として使えるものなのか、実際検証してみたけどベストプラクティスは? など皆様の会社やプロジェクトでも本格的に導入を検討する段階に来ているかもしれません。
そのための情報収集を始める際に「コンテナ仮想化」、「Docker」という単語はまあ出てきますが、一回落ち着いて「Docker」って何ができるんだっけ?というところから復習してみませんか?
この記事ではDockerをVPSに導入し、アプリを動かして「ほら簡単でしょ?」という手順を振り返りたいと思います。「そのへんはもう大丈夫!」という人はよければ研修などの参考記事として使ってください。
この記事でやること
① VPS サーバーを立てる
今回は1時間単位の課金で使える「ConoHa VPS」を使って試していきます。作った環境をすぐに破棄すれば数円でOKですし、そのまま使っても630円/月で運用できます。
② Docker環境を構築する
Docker 公式ドキュメントに従って忠実に環境を構築していきます。
③ Docker でWEBサーバーを立ててみる
基本的な dockerコマンドを使用してコンテナを動かします。
④ docker-compose でもう少し便利に使う
複数のコンテナを一度に立ち上げてくれる機能を使って簡単にいろいろなアプリケーションを実行していきます。
(kubernetesなどのクラスタ環境ではサーバーをまたいでコンテの管理を行うのでもっと複雑になりますが、基本的には docker-compose がもっと高機能になったものと考えても良いかと思います。)
では 順番にやっていきましょう
① VPS サーバーを立てる
どこの会社のものでもよいですが、今回は「1時間単位の課金」ですぐに環境を破棄すれば格安で検証できるConoHa VPS を使います。
まずアカウントを作成しましょう。(Github や Facebook などのアカウントを使って作成することも可能です。)
ログインすると以下の画面が表示されていると思いますので、左側のメニューの「サーバー追加」を押しましょう。
ConoHa VPS はテンプレートがとても豊富で Dockerがインストールされた環境も用意されています。が、今回は導入からやっていきたいので素の Ubuntuで作っていきましょう。
その他入力必須なのは「root パスワード」の部分です。入力が終わったら「追加」を押しましょう。
(1円/1時間)と書いてますね。激安です。
起動するまでしばらく待ちます。作成されたVPSの情報を確認してみます。sshから操作をしたいので、VPSのIPアドレスを確認しておきましょう。
※今回作ったインスタンスはすでに破棄しています
これでDockerを使うためのサーバーを手に入れました。
② Docker環境を構築する
では設定した「root パスワード」とサーバーの「IPアドレス」を使ってsshでログインします。
また、ユーザー作成やrootでのログイン禁止設定など継続して使用する場合にはセキュリティ上の設定もしたいところですが、今回はすぐ潰す予定なので割愛いたしました。
ログイン後は
apt-get update #apt updateでもOKです
apt-get upgrade -y #apt upgrade -y でもOKです
を実行しておきましょう。
Dockerの公式ドキュメント に従いDockerを入れていきます。
http経由でのダウンロードなどを可能にするためのコマンドを実行します。(たいていVPSで初期状態から用意されていますが、手順通りにいきましょう。)
apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
Dockerのパッケージを入手できるようにGPG keyを手に入れましょう。(公式のパッケージで間違いないよ、と確認するためのもの)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
# OK と表示されます
ちゃんと認証情報を入手できたか確認します。
apt-key fingerprint 0EBFCD88
#表示される内容
pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb) <docker@docker.com>
sub rsa4096 2017-02-22 [S]
Docker安定版のパッケージレポジトリを使いしましょう。
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
最後にパッケージをアップデートし、Dockerをインストールしましょう。
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io
ちゃんとDockerをインストールできているかを確認しましょう
dcoker --version # docker -v でもOK
③ Docker でWEBサーバーを立ててみる
ここからが本題の「Dockerってそもそも何ができるんだっけ?」という部分になります。
まずは「Ubuntuの入ったVPS」上で「CentOS」の仮想環境を立ち上げてみましょう。コンテナの実行コマンドは" docker run "です。ここにオプションやコンテナ名を入れて使います。
docker run -i -t centos /bin/bash
# "-i , -t" オプションをつけることでbashの実行をインタラクティブに..などの意味があります
dockerコンテナのコンソールに遷移します。" yum update "とか試してみて終了するには" exit "でOKです。
ではWEBサーバーを立てていきましょう。Apache , Nginx それぞれのコンテナを立てていきます。
まずは Apache(httpD) から
docker run -it -d -p 8080:80 httpd
# "-d"はバックグランドで実行するためのオプションです。
いろいろオプションをつけましたが、"-p"が重要です。左の8080ポートはこのVPSのポート番号、右の80ポートはコンテナの公開ポートになっています。つまりこれは、「Apacheコンテナの80番ポートを、VPSの8080番に紐づけて公開」という意味になります。
コンテナを立ち上げたらブラウザからVPSのIPアドレス:ポート番号にアクセスしてみましょう。
Apacheのデフォルト設定画面…コンテナの中のファイルを書き換えればちゃんとしたWEBページの表示ができてしまいます!
続いて Nginx も立ててみます。
docker run -it -d -p 8888:80 nginx
上記と同じオプションで「Nginxコンテナの80番ポートを、VPSの8888番に紐づけて公開」という意味です。
さて、ここで一旦今まで立ち上げたコンテナを確認してみましょう。
docker ps
# 以下表示内容です。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6c065e6da376 nginx "nginx -g 'daemon of…" 2 minutes ago Up 2 minutes 0.0.0.0:8888->80/tcp wonderful_hypatia
a8b5e87fee68 httpd "httpd-foreground" 9 minutes ago Up 9 minutes 0.0.0.0:8080->80/tcp confident_lederberg
さっき動かしたCentOSのコンテナが表示されていませんね。" docker ps "では「稼働中」のものしか表示されないので全部表示するためにオプションをつけましょう。
docker ps -a
# 以下表示内容です。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6c065e6da376 nginx "nginx -g 'daemon of…" About an hour ago Up About an hour 0.0.0.0:8888->80/tcp wonderful_hypatia
a8b5e87fee68 httpd "httpd-foreground" About an hour ago Up About an hour 0.0.0.0:8080->80/tcp confident_lederberg
# 何度かCentOSの docker run を実行したので複数ありますが本来は1つです、、
cc67fae8bd13 centos "/bin/bash" About an hour ago Exited (0) About an hour ago wizardly_ellis
9117d824fb8d centos "/bin/bash" About an hour ago Exited (0) About an hour ago flamboyant_bouman
c8a461493ed7 centos "/bin/bash" About an hour ago Exited (1) About an hour ago awesome_mclean
その他プションなどについては Dockerの用語は大体「遊戯王カード」で置き換えられることを発見しました! などでも公開していますのでよければ御覧ください。
④ docker-compose でもう少し便利に使う
最後です。
今までで単一のコンテナーの立ち上げ方を記載しましたが、実際のアプリケーション、例えば「WordPress」などは「CentOS」+「Apache」+「MariaDB」+「PHP」などの要素が組み合わさっています。まずこれらひとうひとつのコンテナを立ち上げて、全部のコンテナを同一のサービスとして機能させるのはとても面倒です。また、単一のコンテナにすべての要素を搭載させることも可能ですが、そうすると本来のコンテナのメリットが無くなってしまいます。
※1コンテナ1サービスとして動かしたほうが切り分けが簡単なため、アップデートやちょっとした改修も該当のコンテナを触るだけでよくなります。
ここで複数のコンテナを一度に起動できる "docker-compose" の出番になります。
docker-compose のインストール
こちらも 公式ドキュメント の手順通りに進めていきますが、2行のコマンドを実行するだけです。
docker-composeの安定版をダウンロードします。
curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
ダウンロード先に実行権限を設定して " docker-compose "コマンドを使用できるようにします。
chmod +x /usr/local/bin/docker-compose
以上で docker-compose コマンドが使えるようになりました。
これから docker-compose コマンド一発でアプリケーションを立ち上げていきますが、「WordPress」は Dockerイメージ が配布されており、dockerコマンドでも問題なく動かせるのでもう少し複雑な構成の Rocket.chat というアプリケーションを立ち上げてみましょう。
※ Rocket.chat ..
ビジネスチャットツールである Slack や Teams とほぼ同じ使い方ができるオープンソースのアプリケーションです。無料なのに前者の商用ツールたちと同程度以上の機能を使うことができます。
必要なもの
- " docker-compose "を実行するためのディレクトリ
- " docker-compose.yml "という立ち上げるコンテナの構成が記載されたファイル
まず " docker-compose "を実行するためのディレクトリを下記のコマンドで作成し、そのディレクトリへ移動します。
mkdir -p rocketchat/
cd rocketchat/
" docker-compose.yml "という立ち上げるコンテナの構成が記載されたファイル を作っていきます。このファイルはすでに世の中にあるサービスを使う場合、自分で1から書かないといけないことはそうそうありません。Github の公式レポジトリや Google 検索でほぼ見つけることが可能なので、あとは自分の環境に合わせて少しだけ編集する程度です。今回は 公式のレポジトリ のファイルを使わせていただきましょう。
ではまずディレクトリの中に " docker-compose.yml "というファイルを作り編集していきます。
touch docker-compose.yml
vi docker-compose.yml
以下内容を貼り付けます。
version: '2'
services:
rocketchat:
image: rocketchat/rocket.chat:latest
command: >
bash -c
"for i in `seq 1 30`; do
node main.js &&
s=$$? && break || s=$$?;
echo \"Tried $$i times. Waiting 5 secs...\";
sleep 5;
done; (exit $$s)"
restart: unless-stopped
volumes:
- ./uploads:/app/uploads
environment:
- PORT=3000
- ROOT_URL=http://localhost:3000
- MONGO_URL=mongodb://mongo:27017/rocketchat
- MONGO_OPLOG_URL=mongodb://mongo:27017/local
- MAIL_URL=smtp://smtp.email
# - HTTP_PROXY=http://proxy.domain.com
# - HTTPS_PROXY=http://proxy.domain.com
depends_on:
- mongo
ports:
- 3000:3000
labels:
- "traefik.backend=rocketchat"
- "traefik.frontend.rule=Host: your.domain.tld"
mongo:
image: mongo:4.0
restart: unless-stopped
volumes:
- ./data/db:/data/db
#- ./data/dump:/dump
command: mongod --smallfiles --oplogSize 128 --replSet rs0 --storageEngine=mmapv1
labels:
- "traefik.enable=false"
# this container's job is just run the command to initialize the replica set.
# it will run the command and remove himself (it will not stay running)
mongo-init-replica:
image: mongo:4.0
command: >
bash -c
"for i in `seq 1 30`; do
mongo mongo/rocketchat --eval \"
rs.initiate({
_id: 'rs0',
members: [ { _id: 0, host: 'localhost:27017' } ]})\" &&
s=$$? && break || s=$$?;
echo \"Tried $$i times. Waiting 5 secs...\";
sleep 5;
done; (exit $$s)"
depends_on:
- mongo
# hubot, the popular chatbot (add the bot user first and change the password before starting this image)
hubot:
image: rocketchat/hubot-rocketchat:latest
restart: unless-stopped
environment:
- ROCKETCHAT_URL=rocketchat:3000
- ROCKETCHAT_ROOM=GENERAL
- ROCKETCHAT_USER=bot
- ROCKETCHAT_PASSWORD=botpassword
- BOT_NAME=bot
# you can add more scripts as you'd like here, they need to be installable by npm
- EXTERNAL_SCRIPTS=hubot-help,hubot-seen,hubot-links,hubot-diagnostics
depends_on:
- rocketchat
labels:
- "traefik.enable=false"
volumes:
- ./scripts:/home/hubot/scripts
# this is used to expose the hubot port for notifications on the host on port 3001, e.g. for hubot-jenkins-notifier
ports:
- 3001:8080
#traefik:
# image: traefik:latest
# restart: unless-stopped
# command: >
# traefik
# --docker
# --acme=true
# --acme.domains='your.domain.tld'
# --acme.email='your@email.tld'
# --acme.entrypoint=https
# --acme.storagefile=acme.json
# --defaultentrypoints=http
# --defaultentrypoints=https
# --entryPoints='Name:http Address::80 Redirect.EntryPoint:https'
# --entryPoints='Name:https Address::443 TLS.Certificates:'
# ports:
# - 80:80
# - 443:443
# volumes:
# - /var/run/docker.sock:/var/run/docker.sock
コメントアウトしているのは、SSLアクセスを有効にする場合の設定です。今回アクセスするポート番号は3000番に設定しています。
以上の内容をファイル内にコピペできたら エスケープキー を押し、 " :wp " で上書き保存します。
最後に以下のコマンドでアプリケーションを立ち上げましょう!
docker-compose up -d
初めて立ち上げるときは引っ張るイメージの数やプロセスが多いので結構待ちます。進み具合は下記のコマンドでリアルタイムに確認できます。
docker-compose logs -f
なにやらいろいろなプロセスが実行されていますね。。
数分たったら環境ができていると思いますので、IPアドレス:3000 にアクセスしてアプリケーションを使ってみましょう!
順番に設定していけばすぐ使えます。 Slack 使ったことある人ならほぼそのままのイメージで使えます。(公式もそこを売りにしているみたいですね。)
私はもうこのサーバーが必要ないので、ConoHa VPSのコントロールパネルからこのサーバーを削除しました。
以上、お疲れさまでした。
開発環境をコード化できるので、いつも手元の環境に依存しない同じ環境で開発をすすめることができますし、立ち上げ、削除もすぐにできてしまうのでサービスの運用も簡単になることがメリットだと言われています。ただそこまで実装できている組織は限られていると思いますので、現状基本だけでも抑えておきたいなと思い、またこの内容が他の方の手助けになるとこの上なく嬉しいです。