LinuxでDocker¶
コンテナの設定¶
コンテナの粒度¶
1つのコンテナでいくつものプロセスを稼動させるか、1つのコンテナで1つのプロセスを起動させるか、について。
- sshdを入れてbashで外部から接続してあたかも独立したノードと見せることもできそうだが、それなら仮想マシンの方がよいと思う
- Redmine(Nginx + Unicorn + MySQL)をDockerで動かすとしたら
- 構成1) 3つのコンテナを立て、それぞれでNginx、Unicorn、MySQLを個別に稼動
- 構成2) 1つのコンテナを立て、その中でNginx、Unicorn、MySQLを一緒に稼動
- 構成3) 2つのコンテナを立て、1つでNginx、Unicornを、もう1つでMySQLを稼動
- 構成4) 2つのコンテナを立て、1つでNginxを、もう1つでUnicorn、MySQLを稼動
どれがよいだろう?
Dockerは、アプリケーション単位のコンテナなので、1つのコンテナで1つのプロセスを動かすのが基本。
複数のアプリケーションをまとめて動かすのであれば、Linuxコンテナ(LXC)が向いているようだ。
ケーススタディ1)GrafanaとInfluxDB¶
主に時系列データを可視化するGrafanaと、時系列データに特化したデータベースInfluxDBと2つのアプリケーションを組み合わせたシステムをDockerで実行します。
Dockerでは、アプリケーション毎に1つのコンテナで動かすのが基本なので、GrafanaのコンテナとInfluxDBのコンテナの2つコンテナを使用します。
また、Dockerは停止するとファイルシステムが
コンテナホストのファイアウォールとコンテナのポート¶
コンテナホストのファイアウォールでは閉じている(遮断している)ポートを指定してDockerアプリケーションを起動したところ、外部からそのポートへアクセスができてしまう。
これは、Dockerの実行に指定したポートはInboundではなく、仮想ネットワークへ転送される(NAT)仕組みのため、Linuxのファイアウォール設定で閉じていても通信できてしまう。
Rocky Linux 8でDockerの場合¶
Dockerをインストールしたところ、/etc/firewalld/zones/docker.xmlが生成されていた。
<?xml version="1.0" encoding="utf-8"?>
<zone version="1.0" target="ACCEPT">
<short>docker</short>
<description>zone for docker bridge network interfaces</description>
</zone>
publicゾーンとは別にdockerゾーンが生成されている
~$ firewall-cmd --get-active-zones docker interfaces: docker0 public interfaces: eth0 ~$
ネットワーク¶
同じサーバー上で動く別コンテナへのアクセス¶
同じサーバー上であっても異なるコンテナで動作するサービスへは localhost では接続できません。
永続化¶
Docker コンテナは、イメージからコンテナを生成後、start/stop をしている限りはコンテナ内に作成したファイルは保持されます。しかし、コンテナを破棄して再度イメージからコンテナを生成すると、コンテナ実行中に変更したストレージデータは消えてしまいます。
イメージを更新した場合(例:バージョンアップ)も、コンテナは新たに生成されるので、前のコンテナのストレージデータは引き継ぎできません。
そこで、永続化したいアプリケーションのデータはコンテナの外部に置く必要があります。
永続化の手段¶
- volume
- bind mount
volumeは、dockerが管理する領域の中に永続化データのボリュームを設け、コンテナからそのボリュームをマウントして使用します。
bind mountは、ホストOSの特定ディレクトリをコンテナ内のディレクトリパスにmountして使用します。
ボリューム¶
- ボリュームの作成
docker volume create myvolume
コンテナの管理¶
コマンド¶
旧コマンド¶
コマンド | 内容 | 備考 |
docker run | イメージを取得してコンテナを生成し、コンテナを実行 | |
docker ps | コンテナの一覧 | -a オプションで全てのコンテナを表示(デフォルトは起動中のコンテナ) |
docker start | 作成されたコンテナを実行 | |
docker stop | 実行中のコンテナを停止 | |
docker rm | コンテナを削除 | |
docker image ls | ローカルに格納済みのコンテナイメージの一覧 | |
docker pull | Docker Hub(公式リポジトリ)から既存のイメージをダウンロード | |
docker rmi | イメージの削除 |
新コマンド¶
Docker v1.13以降
コマンド | ||
docker container run | ||
docker container start | 停止しているコンテナを起動 | |
docker container stop | 実行中のコンテナを停止 | |
docker container create | 新しいコンテナの作成 | |
docker container rm | コンテナの削除 | |
docker container ls | コンテナの一覧 | -a オプションで全てのコンテナを表示(デフォルトは実行中のコンテナ) |
docker container attach | 実行中のコンテナに接続 | |
docker container exec | 実行中のコンテナ上でコマンド実行 | |
docker image build | Dockerfileからコンテナイメージを構築 | |
docker image pull | レジストリからイメージを取得 | |
docker image ls | イメージの一覧 | |
docker image rmi | イメージを削除 | |
docker volume ls | ボリュームの一覧 | |
docker volume create | ボリュームの作成 | |
docker volume rm | ボリュームの削除 |
docker container run¶
runは、コンテナのイメージを公式リポジトリから取得し、コンテナを作成し、コンテナを実行します。
書式
docker container run [オプション] IMAGE [COMMAND] [ARGS...]
docker container attach¶
attachは、実行中のコンテナのプロセス(PID=1)を、attach実行ターミナルの標準入力、標準出力、標準エラーに接続します。
docker container exec¶
execは、実行中のコンテナ上で指定したコマンドを実行します。
よく行われるのは、コンテナ上でbashを実行し、そのbashでshell環境の操作をすることです。その場合、-it
オプション指定します。
~$ docker container exec -it mycontainer bash
docker compose¶
複数のプロセスが連携するアプリケーションをDockerで動かす場合、それぞれのプロセスをDockerで起動する必要があります。
docker composeは、この複数のコンテナの組み合わせを管理するコマンドです。
docker compose up¶
docker-compose.ymlを定義し、そのディレクトリでこのコマンドを実行すると、docker-compose.ymlに定義したコンテナを生成し、実行します。
docker compose down¶
docker-compose.ymlのあるディレクトリでこのコマンドを実行すると、docker-compose.ymlに定義したコンテナを停止・破棄します。
すなわち、stopとrmを実行します。
docker compose stop¶
docker-compose.ymlのあるディレクトリでこのコマンドを実行すると、docker-compose.ymlに定義したコンテナを停止します。
docker compose start¶
docker-compose.ymlのあるディレクトリでこのコマンドを実行すると、docker-compose.ymlに定義したコンテナを開始します。
コンテナのイメージ¶
コンテナを実行するには、コンテナイメージが必要となる。イメージは外部から取得するか自分で作成するかとなる。
主要なアプリケーションはコンテナイメージが提要されている。
コンテナの状態¶
状態名 | 内容 |
---|---|
created | |
running | |
paused | |
exited |
手順¶
Grafana¶
InfluxDB と Grafana を双方 Docker 上で実行します。
docker composeで実行¶
InfluxDBとGrafanaの2つのDockerコンテナを生成・実行するとき、docker composeを用いると簡単に実行できます。
docker-compose.ymlの作成¶
docker composeでは、実行するコンテナ群の定義を docker-compose.yml ファイルに記述します。
version: "3"
services:
influxdb:
image: influxdb
container_name: influxdb
restart: always
volumes:
- ./influxdb:/var/lib/influxdb2
ports:
- 8086:8086
- 8083:8083
environment:
DOCKER_INFLUXDB_INIT_MODE: setup
DOCKER_INFLUXDB_INIT_USERNAME: myname
DOCKER_INFLUXDB_INIT_PASSWORD: mypassword
DOCKER_INFLUXDB_INIT_ORG: myorg
DOCKER_INFLUXDB_INIT_BUCKET: mybucket
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: my_secret_token
grafana:
image: grafana/grafana
container_name: grafana
user: "root"
restart: always
volumes:
- ./grafana:/var/lib/grafana
depends_on:
- influxdb
ports:
- 3000:3000
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- InfluxDBのアカウント、パスワード、APIトークンなどを記述できます。
- パスワードは文字数の規定あり(5文字では起動時にエラー)
- Grafanaのパスワードは初回接続時に変更を促された
イメージの作成¶
Ubuntuユーザーランドのイメージ作成¶
まず、作業ディレクトリを作成し、Dockerfileを記述します。
work$ mkdir hello-ubuntu work$ cd hello-ubuntu hello-ubuntu$ vi Dockerfile
Dockerfileを作成します。ここでは、ubuntuイメージの最新を取得し、apt update で最新化、apt installで追加パッケージをインストールします。
FROM ubuntu:latest RUN apt update -y && apt install -y iputils-ping net-tools curl
イメージを作成します。
hello-ubuntu$ docker image build -t test-image:v1 .
イメージが生成されたことを確認
hello-ubuntu$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE test-image v1 82e007336365 36 minutes ago 121MB ubuntu latest 58db3edaf2be 2 weeks ago 77.8MB
イメージからコンテナを生成し実行します。
hello-ubuntu$ docker run --name test-container1 -it test-image:v1 /bin/bash
- -it オプションを指定し、標準入力とターミナルを使用
参考資料¶
雑多¶
Linux女子部「Docker勉強会」資料(2014-06-19 講師: 中井悦司 氏)¶