Docker & Kubernetes 入門 #6

Kenta Kosugi
9 min readOct 2, 2019

--

Volume #2

前回は postgres のイメージを Docker Hub から pull して起動しました。その際、postgres が内部で溜め込むデータは気にせずに Docker コンテナを起動、再起動(コンテナの削除、起動)し、再起動前に貯めたデータが消失することを確認しました。

Docker には Volume という機能があり、コンテナ上の特定のディレクトリをホスト上にマウントしてデータを保存することができます。

Volume 機能を試すために下記コマンドで前回起動したコンテナを削除しておきます。また、カレントディレクトリに data ディレクトリを作成しておきます。

$ docker rm mypostgres
$ mkdir data

Volume 機能を利用した以下のコマンドで再度 postgres を起動します。

$ docker run -d --name mypostgres -p 5432:5432 -e POSTGRES_USER=redhat -e POSTGRES_PASSWORD=redhat -e POSTGRES_DB=mydb -v $(pwd)/data:/var/lib/postgresql/data postgres:12
402921ad37a77a74f014d787e977bd2dfef934a8bd72aef565bc76e89183c5f2

Docker コンテナの起動に成功したら先ほど作成したホスト側(Mac)の data ディレクトリの中身を確認してみます。

$ ls -la ./data/
total 112
drwx------@ 26 kkosugi staff 832 10 2 21:32 .
drwxr-xr-x+ 59 kkosugi staff 1888 10 2 21:31 ..
-rw------- 1 kkosugi staff 3 10 2 21:32 PG_VERSION
drwx------ 6 kkosugi staff 192 10 2 21:32 base
drwx------ 65 kkosugi staff 2080 10 2 21:32 global
drwx------ 2 kkosugi staff 64 10 2 21:32 pg_commit_ts
drwx------ 2 kkosugi staff 64 10 2 21:32 pg_dynshmem
-rw------- 1 kkosugi staff 4535 10 2 21:32 pg_hba.conf
-rw------- 1 kkosugi staff 1636 10 2 21:32 pg_ident.conf
drwx------ 5 kkosugi staff 160 10 2 21:32 pg_logical
drwx------ 4 kkosugi staff 128 10 2 21:32 pg_multixact
drwx------ 3 kkosugi staff 96 10 2 21:32 pg_notify
drwx------ 2 kkosugi staff 64 10 2 21:32 pg_replslot
drwx------ 2 kkosugi staff 64 10 2 21:32 pg_serial
drwx------ 2 kkosugi staff 64 10 2 21:32 pg_snapshots
drwx------ 2 kkosugi staff 64 10 2 21:32 pg_stat
drwx------ 4 kkosugi staff 128 10 2 21:32 pg_stat_tmp
drwx------ 3 kkosugi staff 96 10 2 21:32 pg_subtrans
drwx------ 2 kkosugi staff 64 10 2 21:32 pg_tblspc
drwx------ 2 kkosugi staff 64 10 2 21:32 pg_twophase
drwx------ 4 kkosugi staff 128 10 2 21:32 pg_wal
drwx------ 3 kkosugi staff 96 10 2 21:32 pg_xact
-rw------- 1 kkosugi staff 88 10 2 21:32 postgresql.auto.conf
-rw------- 1 kkosugi staff 26588 10 2 21:32 postgresql.conf
-rw------- 1 kkosugi staff 36 10 2 21:32 postmaster.opts
-rw------- 1 kkosugi staff 94 10 2 21:32 postmaster.pid

なにやら postgres に関連しそうなデータ群が作成されているのが確認できます。-v オプションを利用することでホストの data ディレクトリを Docker コンテナ内の /var/lib/postgresql/data としてマウントしています。そのため、Docker コンテナ内ではなく、ホスト側に postgres に必要なデータ群が保存されることになり、コンテナを削除した後、再起動しても前の状態と同じデータで処理を継続することが可能になります。

/var/lib/postgresql/data は postgres 用のデータ保存用ディレクトリであり、これはアプリケーションの作りによって変わります。mysql であれば /var/lib/mysql ですし、nginx であれば /usr/share/nginx/html です。

以下のコマンドを利用することで Docker コンテナの詳細情報を確認できます。Volume については Mounts 項目で確認できます。

$ docker inspect mypostgres
// 略
"Mounts": [
{
"Type": "bind",
"Source": "/Users/kkosugi/data",
"Destination": "/var/lib/postgresql/data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
// 略

では前回同様、INSERT 文を実行してからコンテナを削除して、再起動してみます。太字の箇所を実行してください。

$ docker exec -it mypostgres /bin/bash
root@402921ad37a7:/# psql -U redhat -d mydb
psql (12beta4 (Debian 12~beta4-1.pgdg100+1))
Type "help" for help.
mydb=# CREATE TABLE CUSTOMER(
mydb(# ID bigint,
mydb(# SSN char(25),
mydb(# NAME varchar(64),
mydb(# CONSTRAINT CUSTOMER_PK PRIMARY KEY(ID)
mydb(# );
CREATE TABLE
mydb=# INSERT INTO CUSTOMER (ID,SSN,NAME) VALUES (10, 'CST01002','Joseph Smith');
INSERT 0 1
mydb=# INSERT INTO CUSTOMER (ID,SSN,NAME) VALUES (11, 'CST01003','Nicholas Ferguson');
INSERT 0 1
mydb=# INSERT INTO CUSTOMER (ID,SSN,NAME) VALUES (12, 'CST01004','Jane Aire');
INSERT 0 1
mydb=#

control + d を 2 回実行して Docker コンテナ内から抜けます。

コンテナを削除後、同じイメージを使って再起動します。

$ docker stop mypostgres
mypostgres
$ docker rm mypostgres
mypostgres
$ docker run -d --name mypostgres -p 5432:5432 -e POSTGRES_USER=redhat -e POSTGRES_PASSWORD=redhat -e POSTGRES_DB=mydb -v $(pwd)/data:/var/lib/postgresql/data postgres:12
85d6598105409cae01a1cf3dafa3a11bbd8a40ab39694fe46158d63991072d48

Docker コンテナにアタッチして INSERT したデータが残っていることを確認します。

$ docker exec -it mypostgres /bin/bash
root@85d659810540:/# psql -U redhat -d mydb
psql (12beta4 (Debian 12~beta4-1.pgdg100+1))
Type "help" for help.
mydb=# \dt
List of relations
Schema | Name | Type | Owner
--------+----------+-------+--------
public | customer | table | redhat
(1 row)
mydb=# select * from customer;
id | ssn | name
----+---------------------------+-------------------
10 | CST01002 | Joseph Smith
11 | CST01003 | Nicholas Ferguson
12 | CST01004 | Jane Aire
(3 rows)
mydb=#

データが残っていることが確認できました。

おまけ

宣伝ではないですが、データを大量に扱う人は JetBrains 社の DataGrip がおすすめです。前前職のみずほ証券のときは大量の DB(Sybase/Oracle/SQL Server)、大量のテーブルを処理する必要があり、このツールに非常に助けてもらいました。

Docker 上のテーブルも以下のように簡単に確認できます。

JetBrains DataGrip

今回は Volume 機能についてみてみました。

--

--

Kenta Kosugi
Kenta Kosugi

Written by Kenta Kosugi

Javaアプリケーションサーバーの開発からCORBA製品のサポート、QA、証券外務員(第一種免許)、ストレージ屋、アーキテクト、SaaS屋と一貫性のない道を歩んでいます。Red Hatに復帰しました。

No responses yet