1. 概要

この記事では、Dockerを使用してデータベースを管理する方法を確認します。

最初の章では、ローカルマシンへのデータベースのインストールについて説明します。 次に、データの永続性がコンテナ間でどのように機能しているかを確認します。

結論として、Docker本番環境にデータベースを実装することの信頼性について説明します。

2. Dockerイメージをローカルで実行する

2.1. 標準のDockerイメージから開始

まず、 DockerDesktopをインストールする必要があります。 次に、DockerHubからデータベースの既存のイメージを見つける必要があります。 見つかったら、ページの右上隅から dockerpullコマンドを選択します。

このチュートリアルではPostgreSQLを使用するため、コマンドは次のようになります。

$docker pull postgres

ダウンロードが完了すると、 docker runコマンドは、Dockerコンテナ内に実行中のデータベースを作成します。 PostgreSQLの場合、POSTGRES_PASSWORD環境変数を-eオプションで指定する必要があります。

$docker run -e POSTGRES_PASSWORD=password postgres

次に、データベースコンテナの接続をテストします。

2.2. Javaプロジェクトをデータベースに接続する

簡単なテストをしてみましょう。 JDBCデータソースを使用して、ローカルJavaプロジェクトをデータベースに接続します。 接続文字列は、localhostのデフォルトのPostgreSQLポート5432を使用する必要があります。

jdbc:postgresql://localhost:5432/postgres?user=postgres&password=password

エラーは、ポートが開かれていないことを通知する必要があります。 実際、データベースはコンテナネットワークの内部からの接続をリッスンしており、Javaプロジェクトはその外部で実行されています。

これを修正するには、コンテナポートをローカルホストポートにマップする必要があります。 PostgreSQLにはデフォルトのポート5432を使用します。

$docker run -p 5432:5432 -e POSTGRES_PASSWORD=password postgres

接続は現在機能しており、JDBCデータソースを使用できるはずです。

2.3. SQLスクリプトの実行

これで、たとえばシェルからデータベースに接続して、初期化スクリプトを実行できます。

まず、実行中のコンテナIDを見つけましょう。

$docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS          PORTS                    NAMES
65d9163eece2   postgres   "docker-entrypoint.s…"   27 minutes ago   Up 27 minutes   0.0.0.0:5432->5432/tcp   optimistic_hellman

次に、インタラクティブな-itオプションを指定してdocker execコマンドを実行し、コンテナー内でシェルを実行します

$docker exec -it 65d9163eece2 bash

最後に、コマンドラインクライアントを使用してデータベースインスタンスに接続し、SQLスクリプトを貼り付けることができます。

root@65d9163eece2:/# psql -U postgres
postgres=#CREATE DATABASE TEST;
CREATE TABLE PERSON(
  ID INTEGER PRIMARY KEY,
  FIRST_NAME VARCHAR(1000),
  LAST_NAME VARCHAR(1000)
);
...

たとえば、ロードするダンプファイルが大きい場合は、コピー貼り付けを避ける必要があります。 docker execコマンドを使用する代わりに、ホストから直接importコマンドを実行できます

$docker exec 65d9163eece2 psql -U postgres < dump.sql

3. Dockerボリュームを使用してデータを永続化する

3.1. なぜボリュームが必要なのですか?

基本的なセットアップは、同じコンテナーを使用している限り機能し、再起動が必要になるたびに docker container stop /startを使用します。 docker runを再度使用すると、新しい空のコンテナーが作成され、データが失われます。 実際、Dockerはデフォルトで一時ディレクトリ内にデータを保持します。

次に、このボリュームマッピングを変更する方法を学習します。

3.2. Dockerボリュームのセットアップ

最初のタスクは、コンテナーを検査して、データベースで使用されているボリュームを確認することです。

$docker inspect -f "{{ .Mounts }}" 65d9163eece2
[{volume f1033d3 /var/lib/docker/volumes/f1033d3/_data /var/lib/postgresql/data local true }] 

ボリュームf1033d3がコンテナディレクトリ/var / lib / postgresql /dataを一時ディレクトリ/var / lib / docker / bytes /f1033d3/にマップしていることがわかります。ホストファイルシステムに作成された_data

2.1章で使用したdockerrunコマンドに-vオプションを追加して、このマッピングを変更する必要があります。

$docker run -v C:\docker-db-volume:/var/lib/postgresql/data -e POSTGRES_PASSWORD=password postgres

これで、 C:\docker-db-volumeディレクトリに作成されたデータベースファイルを確認できます。 この専用記事で高度なボリューム構成を見つけることができます。

その結果、 docker run command を使用するたびに、データはさまざまなコンテナーの実行とともに保持されます。

また、チームメンバー間または異なる環境間で構成を共有したい場合もあります。 Docker Composeファイルを使用できます。このファイルは、毎回新しいコンテナーを作成します。 この場合、ボリュームは必須です。

次の章では、実稼働環境でのDockerデータベースの特定の使用法について説明します。

4. 本番環境でのDockerの操作

Docker Composeは、構成を共有し、コンテナーをステートレスサービスとして管理するのに最適です。 サービスに障害が発生した場合、またはワークロードを処理できない場合は、新しいコンテナーを自動的に作成するようにDockerComposeを構成できます。 これは、設計上ステートレスであるRESTバックエンドの本番クラスターを構築する場合に非常に役立ちます。

ただし、データベースはステートフルであり、その管理はより複雑です:さまざまなコンテキストを確認しましょう。

4.1. シングルインスタンスデータベース

テスト用または本番用に、ダウンタイムの期間(展開、バックアップ、または障害時)を許容する重要ではない環境を構築していると仮定します。

この場合、高可用性クラスターは必要ありません。単一インスタンスのデータベースにDockerComposeを使用するだけです。

  • コンテナは同じマシンで実行されるため、データストレージにシンプルなボリュームを使用できます
  • グローバルモードを使用して、一度に1つのコンテナーを実行するように制限できます。

ミニマリストの実例を見てみましょう:

version: '3'
services:       
  database:
    image: 'postgres'
    deploy:
      mode: global
    environment:
      - POSTGRES_PASSWORD=password
    ports:
      - "5432:5432"
    volumes:
      - "C:/docker-db-volume:/var/lib/postgresql/data"

この構成を使用すると、本番環境では一度に1つのコンテナーのみが作成され、 C:\docker-db-volumeディレクトリのデータファイルが再利用されます。

でも、 この構成では、定期的なバックアップを作成することがさらに重要です。 構成エラーの場合、このディレクトリはコンテナによって消去または破損される可能性があります

4.2. 複製されたデータベース

ここで、本番環境が重要であると仮定しましょう。

この場合、 DockerSwarmKubernetesなどのオーケストレーションツールは、ステートレスコンテナで役立ちます。これらは、負荷分散、フェイルオーバー、自動スケーリング機能を備えた垂直および水平クラスタリングを提供します。 。

残念ながら、データベースコンテナはステートフルであるため、これらのソリューションはボリュームレプリケーションメカニズムを提供しません。

一方、自家製の構成を構築すると、深刻なデータ損失につながる可能性があるため、危険です。 例えば:

  • ボリュームにNFSやNASなどの共有ストレージを使用しても、データベースが別のインスタンスで再起動されたときにデータが失われないことを保証することはできません
  • マスタースレーブクラスターでは、 Dockerオーケストレーションに複数のマスターノードを選択させるのは一般的なエラーであり、データの破損につながります

これまでのところ、さまざまなオプションは次のとおりです。

  • データベースにDockerを使用しないでください。また、データベース固有またはハードウェアレプリケーションメカニズムを実装してください
  • データベースにDockerを使用せず、 OpenShift、Amazon AWS、AzureなどのPlatform-as-a-Serviceソリューションにサブスクライブします
  • KubeDBPortworxなどのDocker固有のレプリケーションメカニズムを使用します

5. 結論

この記事では、開発、テスト、および重要ではない本番環境に適した基本構成を確認しました。

最後に、高可用性環境で使用する場合、Dockerには欠点があると結論付けました。 したがって、回避するか、データベースクラスターに特化したソリューションと組み合わせる必要があります。