Dockerデータ管理(ボリューム対bid mount)


Dockerデータ管理


Dockerコンテナのデータ管理...


Dockerは、アプリケーションをコンテナとして実行して削除する場合があります.
コンテナを削除すると、コンテナ内のデータは一緒に消えます.
私の場合、AWS EC 2環境でDockerランタイムを配置し、配置とCI/CDテストのためにJenkinsをコンテナに入れました.
Jenkinsの内部には、認証情報やパイプライン情報など、さまざまな情報が含まれています.
もし私がうっかりコンテナを削除したら、すべての情報が失われます.
Jenkinsの他にRedis MysqlのようなDBもありますあるいはログを収集するコンテナ...
多くのアプリケーションでは、コンテナのライフサイクルの影響を受けずにデータの持続性を確保する必要があります.
Dockerコンテナでのデータ管理は重要な話題です.

Dockerボリュームとbind mount



DockerはDockerボリュームとbind mountという名前の
2つの方法をお勧めします.
この2つの方法でDockerコンテナ内のデータの永続性を確保する方法を見てみましょう.
Docker公式文書ボリューム
Dockerデータの保存の詳細については、上記のAPIを参照してください.

実習環境

  • AWS EC 2(公認IP:13.124.73.347)
  • を利用
  • Dockerボリューム:Jenkins画像を利用した
  • bind mount:Nginxイメージ利用
  • Docker Volume


    ドッキングボリュームは、ファイルシステムのDocker areaと呼ばれる部分をコンテナにマウントする方法です.
    次のコマンドを使用して、ボリュームを作成および表示することもできます.

    Dockerボリュームの作成と情報の検証

    # 도커 볼륨 생성
    $ docker volume create my-vol
    
    # 도커 볼륨 목록 확인
    $ docker volume ls
    
    # 볼륨 정보 확인
    $ docker volume inspect my-vol
    [
        {
            "CreatedAt": "2022-03-20T06:22:33Z",
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
            "Name": "my-vol",
            "Options": {},
            "Scope": "local"
        }
    ]
    inspectコマンドは、上記の結果を検証します.
    MountPointで見られる「/var/lib/docker/volumes」は、概念図のファイルシステム内部の「Docker area」です.
    コンテナの特定のパスをパスの{ボリューム名}/dataにマウントできます.

    Jenkins容器駆動


    次に、作成したmy-volを使用してJenkinsコンテナを駆動します.
    DockerHub Jenkins Repository
    画像はDocker Hub上のJenkins画像を使用します.
    Jenkinsイメージの場合、Dockerコンテナで最初の実行時
    [/var/jenkins home/secrets/initialAdminPassword]値が必要です.
    ログで検証するか、docker execコマンドでコンテナshellに直接アクセスして検証できます.
    上記で作成したmy-volにマウントして、対応する値を検索します.
    コマンドは次のとおりです.
    # 컨테이너 생성
    $ docker run -itd -v my-vol:/var/jenkins_home --name jenkins -p 8080:8080 jenkins/jenkins:jdk11
    
    # 실행 결과
    Unable to find image 'jenkins/jenkins:jdk11' locally
    jdk11: Pulling from jenkins/jenkins
    e4d61adff207: Pull complete
    eacef06daf30: Pull complete
    ca581b0141a3: Pull complete
    d872c65909bb: Pull complete
    bcce550e05a9: Pull complete
    3461f061a833: Pull complete
    3b6f8a58a68d: Pull complete
    6d47f55855ba: Pull complete
    baa80a92c8e4: Pull complete
    39889d888af7: Pull complete
    18b5e0e36b4c: Pull complete
    a53e22d026ad: Pull complete
    a281963da5b5: Pull complete
    2366689c95a7: Pull complete
    27cbe8a0f233: Pull complete
    fffccee1c284: Pull complete
    a6afec98241f: Pull complete
    Digest: sha256:a5215b81a7f6e111ed6625b342521145e24c232891615be29ce3a251a631feac
    Status: Downloaded newer image for jenkins/jenkins:jdk11
    b188f3fd411d3ac75c7795b7fdd8371b79ae8612ed57669f958458439da1a8c6
    
    # 컨테이너 확인
    $ docker ps
    
    # 결과
    CONTAINER ID   IMAGE                   COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
    b188f3fd411d   jenkins/jenkins:jdk11   "/sbin/tini -- /usr/…"   49 seconds ago   Up 48 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 50000/tcp   jenkins
    -vオプションは、以前に作成したmy-volボリュームをコンテナの/var/jenkins homeパスにロードします.
    Jenkins/jenkins:jdk 11イメージは存在しません.インポートして起動が完了したことを確認できます.
    ポート8080は-pオプションでオープンしているため、JenkinsアプリケーションがEC 2に正常に配備されているかどうかを確認します.

    Jenkinsドライブ成功!
    ただしJenkinsのドライバのために管理者パスワードを入力する必要があります
    ボリュームがインストールされていない場合は、ログを確認するかdocker execコマンドを使用してファイルに直接アクセスする必要があります.
    ただし、my-volを使用して/var/jenkins homeパスをマウントしているため、ローカルホストのmy-vol格納場所でデータを表示できます!
    # 컨테이너 정보 확인
    $ docker inspect {jenkins continer id}
    
    # 결과
    ... 중간생략
    "Mounts": [
                {
                    "Type": "volume",
                    "Name": "my-vol",
                    "Source": "/var/lib/docker/volumes/my-vol/_data",
                    "Destination": "/var/jenkins_home",
                    "Driver": "local",
                    "Mode": "z",
                    "RW": true,
                    "Propagation": ""
                }
    ]
    ... 이하생략
    inspectコマンドを使用してコンテナ情報を確認します.
    すべてのその他を省略してMountsセクションを表示
    my-volというボリュームがインストールされています.
    ローカルホスト上の/var/lib/docker/volumes/my-vol/dataをソースとします.
    コンテナの/var/jenkins homeはDestinationであることがわかります.
    # 로컬 호스트의 Source 경로로 이동
    $ cd /var/lib/docker/volumes/my-vol/_data
    
    $ ls -al
    total 84
    drwxr-xr-x 12 ubuntu ubuntu 4096 Mar 20 06:26 .
    drwx-----x  3 root   root   4096 Mar 20 06:22 ..
    drwxr-xr-x  4 ubuntu ubuntu 4096 Mar 20 06:25 .cache
    drwxr-xr-x  3 ubuntu ubuntu 4096 Mar 20 06:25 .java
    -rw-r--r--  1 ubuntu ubuntu    0 Mar 20 06:26 .lastStarted
    -rw-r--r--  1 ubuntu ubuntu 1661 Mar 20 06:26 config.xml
    -rw-r--r--  1 ubuntu ubuntu   50 Mar 20 06:25 copy_reference_file.log
    -rw-r--r--  1 ubuntu ubuntu  156 Mar 20 06:25 hudson.model.UpdateCenter.xml
    -rw-------  1 ubuntu ubuntu 1712 Mar 20 06:25 identity.key.enc
    -rw-r--r--  1 ubuntu ubuntu  171 Mar 20 06:25 jenkins.telemetry.Correlator.xml
    drwxr-xr-x  2 ubuntu ubuntu 4096 Mar 20 06:25 jobs
    -rw-r--r--  1 ubuntu ubuntu  907 Mar 20 06:25 nodeMonitors.xml
    drwxr-xr-x  2 ubuntu ubuntu 4096 Mar 20 06:25 nodes
    drwxr-xr-x  2 ubuntu ubuntu 4096 Mar 20 06:25 plugins
    -rw-r--r--  1 ubuntu ubuntu   64 Mar 20 06:25 secret.key
    -rw-r--r--  1 ubuntu ubuntu    0 Mar 20 06:25 secret.key.not-so-secret
    drwx------  2 ubuntu ubuntu 4096 Mar 20 06:25 secrets
    -rw-rw-r--  1 ubuntu root   7152 Mar 15 14:55 tini_pub.gpg
    drwxr-xr-x  2 ubuntu ubuntu 4096 Mar 20 06:26 updates
    drwxr-xr-x  2 ubuntu ubuntu 4096 Mar 20 06:25 userContent
    drwxr-xr-x  3 ubuntu ubuntu 4096 Mar 20 06:25 users
    drwxr-xr-x 11 ubuntu ubuntu 4096 Mar 20 06:25 war
    
    # Destination 경로/secrets/initialAdminPassword
    $ cat secrets/initialAdminPassword
    
    # 결과 확인
    80f24341f4bf449b8d3ad95d61061511
    もしそうであれば、ローカルホストでcdコマンドを使用してソースパスのデータを表示します.
    いくつかのファイルが含まれており、AdministratorPassword値を検索するために必要な機密であるフォルダが表示されます.
    catコマンドを使用してPassword値を問合せ、Jenkins Webコンソールに結果値を入力します.

    認証に成功しました.

    コンテナを削除してデータを確認


    Jenkinsコンテナを削除し、データを確認します.
    # Jenkins 컨테이너 정지
    $ docker stop {jenkins container id}
    
    # Jenkins 컨테이너 삭제
    $ docker rm {jenkins container id}

    docker rmコマンドを使用してコンテナを削除し、
    コンテナのソースパス非表示/var/lib/docker/volumes/my-volと内部ファイルがまだ存在することがわかります.

    bind mount


    bind mountは、ローカルホスト上の特定のディレクトリをコンテナにロードする方法です.
    Dockerボリュームとの違いは、Dockerボリュームのインストールポイントを管理し続けることです.
    bind mountの場合、Dockerによって作成されるのではなく、ローカルホストの特定のパスであるため、Dockerは管理されません.

    mountターゲットディレクトリの作成

    # 마운트 대상 폴더 및 테스트 파일 생성
    $ mkdir /app
    $ cat <<EOF > index.html
    > hello world
    > EOF
    まず、ルートパスにappというフォルダを作成し、内部にindexを作成します.htmlファイルが作成されました.

    Nginx容器駆動


    bind mountはnginxイメージで簡単なテストを行います.
    Nginx画像のルートディレクトリは/usr/share/nginx/htmlです.
    DockerHub Nginx Repository
    # nginx 컨테이너 생성
    docker run -itd -v /app:/usr/share/nginx/html --name nginx -p 80:80 nginx
    docker runコマンドを使用してnginxコンテナを作成します.
    ポートは80で、前に作成した/appフォルダをNginxのルートディレクトリにロードします.
    正常にインストールされている場合は、デプロイメントコンテナの80ポートに接続します.
    hello worldが表示されなければなりません.

    正常な出力のhello worldが見えます!

    n/a.結論


    Docker Volume vs bind mount


    これまでDocker Volumeとbind Mountを使用してドックコンテナ内のデータを管理してきました.
    では、どちらの方法がいいのでしょうか.
    まず、Dockerドキュメントに従って、Dockerボリュームを使用することは、ドッキングコンテナでデータを維持する最も簡単な方法です.また、セキュリティの観点からDockerボリュームの方が安全です.
    Docker VolumeはDockerによって管理されるため、ユーザーが注意しなければならないことは少ない.
    場合によってはbind mountの使用がより適切である場合があります.例えば、git reposirotiをローカルで開発したり、git reposirotiをクローンしたり、頻繁に変更したりします.

    リファレンス

  • Docker公式文書ボリューム
  • DockerHub Jenkins Repository
  • DockerHub Nginx Repository