Docker & Kubernetes 入門 #5

Kenta Kosugi
7 min readSep 18, 2019

--

Volume #1

Postgres の起動

Docker Hub の postgres イメージを利用してコンテナを起動してみます。

$ docker run -d --name mypostgres -p 5432:5432 -e POSTGRES_USER=redhat -e POSTGRES_PASSWORD=redhat -e POSTGRES_DB=mydb postgres:12
Unable to find image 'postgres:12' locally
12: Pulling from library/postgres
b8f262c62ec6: Pull complete
fe6da876d968: Pull complete
46b9d53972f5: Pull complete
23a11bddcc75: Pull complete
d6744ba78bdc: Pull complete
8d95423a7aa9: Pull complete
8590ba4183e5: Pull complete
ed97b9b8e039: Pull complete
1fcabeae6f64: Downloading [=============================================> ] 74.72MB/81.42MB
c215675d3379: Download complete
1f251260e65b: Download complete
c2a3c87217a3: Download complete
8eb04dc0183c: Download complete
7d50ad2c26e1: Download complete

はじめて -d オプションが登場しました。これはデタッチドモードでコンテナを起動する方法です。これまでの説明では control + c を押すまでコンテナが終了しませんでしたが、このオプションを付与することで docker run コマンド自体はすぐに終了し、裏でコンテナが引き続き動作します。

-e オプションを利用すると環境変数を起動するコンテナに渡すことが可能になります。postgres では渡された環境変数を元に起動時に初期化処理を実行することができるようつくられています。

  • POSTGRES_USER : postgres のユーザーを指定します。
  • POSTGRES_PASSWORD : 上記ユーザーのパスワードを指定します。
  • POSTGRES_DB : データベースを作成します。

Postgres が起動しているコンテナにアタッチ

docker ps コマンドを利用して postgres の起動状況を確認します。

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ab7481765e7f postgres:12 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp mypostgres

この mypostgres コンテナに docker exec コマンドでアタッチします。

$ docker exec -it mypostgres /bin/bash
root@ab7481765e7f:/# psql -U redhat -d mydb
psql (12beta4 (Debian 12~beta4-1.pgdg100+1))
Type "help" for help.
mydb=#

ここでは簡単なテーブルを作成して、INSERT してみます。以下の文を貼り付けてください。

CREATE TABLE CUSTOMER(
ID bigint,
SSN char(25),
NAME varchar(64),
CONSTRAINT CUSTOMER_PK PRIMARY KEY(ID)
);

以下のような出力になります。

mydb=# CREATE TABLE CUSTOMER
mydb-# (
mydb(# ID bigint,
mydb(# SSN char(25),
mydb(# NAME varchar(64),
mydb(# CONSTRAINT CUSTOMER_PK PRIMARY KEY(ID)
mydb(# );
CREATE TABLE

\dt コマンドを入力してテーブルを出力します。\ は option キーを押下しながら¥キーをうつと入力することができます。

mydb=# \dt
List of relations
Schema | Name | Type | Owner
--------+----------+-------+--------
public | customer | table | redhat
(1 row)

続けて以下の SQL 文をコピー&ペーストしてテーブルに 3 行分挿入します。

INSERT INTO CUSTOMER (ID,SSN,NAME) VALUES (10, 'CST01002','Joseph Smith');
INSERT INTO CUSTOMER (ID,SSN,NAME) VALUES (11, 'CST01003','Nicholas Ferguson');
INSERT INTO CUSTOMER (ID,SSN,NAME) VALUES (12, 'CST01004','Jane Aire');

こんな感じになります。

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

select 文を利用してデータを確認します。

mydb=# select * from customer;
id | ssn | name
----+---------------------------+-------------------
10 | CST01002 | Joseph Smith
11 | CST01003 | Nicholas Ferguson
12 | CST01004 | Jane Aire
(3 rows)

データが確認できました。
control + d を 2 回投入して、ターミナルに戻ります。

コンテナの停止と削除

ここで mypostgres を停止して削除

$ 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 postgres:12
6f34ea0c0b1a332c2d0e968fc1a2891501277deb0ee3d8257a2506aa9ddd7c40

再び mypostgres コンテナにアクセスし、テーブルを表示。

$ docker exec -it mypostgres /bin/bash
root@6f34ea0c0b1a:/# psql -U redhat -d mydb
psql (12beta4 (Debian 12~beta4-1.pgdg100+1))
Type "help" for help.
mydb=# \dt
Did not find any relations.
mydb=#

当たり前と言えば当たり前なのですが、コンテナを削除してから同一のイメージで再度起動すると、コンテナ削除前に操作したデータベースへのテーブル作成処理や、インサート処理が反映されません。
postgres 自体は Docker さえ用意できれば Docker Hub を通じてどこでも実行できることがわかりました。しかし、上記のように postgres が持っているデータ自体は可搬性がないことがわかります。アプリケーションに可搬性を持たせられるようになったのとは裏腹にデータには可搬性がないのです。このような問題を解決するために、Persistent Volume が存在します。

次回はこの Persistent Volume を使用して postgres を起動してみます。

--

--

Kenta Kosugi
Kenta Kosugi

Written by Kenta Kosugi

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

No responses yet