tech_memo / Docker


tech_memo

コンテナパフォーマンスチューニング

コンテナのulimit上限値設定について

  • コンテナ内のopen filesの値は、dockerおよびコンテナのデーモンで設定されている模様
    /etc/systemd/system/multi-user.target.wants/docker.service:LimitNOFILE=1048576
    /etc/systemd/system/multi-user.target.wants/containerd.service:LimitNOFILE=1048576
  • open fileについて、その他わかってること
    • open fileはunlimitedは指定できない
    • /etc/secuilityで有効な上限値はカーネルパラメータfs.nr_openの値
    • コンテナ内のユーザはopen files は、カーネルパラメータfs.nr_openと等しい
  • ユーザがリソースを食いつぶすようなことがあれば、上記ファイルの設定値を書き換えて、デーモン再起動でいける(はず)

レジストリ操作CLI

/var/lib/docker/overlay2 が肥大化した時の対処

インストール


AWS

RHEL

コンテナ実行

  • 一例
    docker run --name <コンテナ名> -d --rm \
    -p <ホスト側のポート番号>:<コンテナ側のポート番号> \
    -v <ホスト側のディレクトリ><コンテナ側のマウントポイント>[:<オプション>] 
    <イメージ名>
    • -d :デタッチモード。バックグラウンドで実行する
    • --rm:コンテナ停止時にコンテナ削除を同時に行う

環境変数を設定して実行

  • -eオプションで環境変数を設定可能
    docker run --name mytest -d -e MYENV="SAMPLE VALUE" docker/whalesay

ストレージ


Docker Volume

特徴

  • ホスト上のディレクトリをマウントさせる
  • 複数コンテナで共有可能
  • ホスト上で直接操作はNG

作成方法

  • 作成コマンド
    docker volume create <ボリューム名>
  • 確認コマンド
    docker volume ls
    docker volume inspect <ボリューム名>
    • 実態はホスト上の下記に作成される
      /var/lib/docker/volumes/<ボリューム名>

マウント方法(--mountオプションを使う場合。推奨)

  • --mountオプションのあとに、source=<ボリューム名>target=<マウント先>を指定する
    docker run --name mount-c2 -itd --mount source=vol1,target=/app nginx:latest
  • readonlyオプションを付加する場合
    docker run --name mount-c2 -itd --mount source=vol1,target=/app,readonly nginx:latest

マウント方法(-vオプションを使う場合)

  • 下記vol1がボリューム名。実行時点で存在しない場合は自動で作成される
    docker run -itd --name mount-c1 -v vol1:/app nginx:latest
  • readonlyオプションを付加する場合
    docker run --name mount-c4 -itd -v vol1:/app/:ro nginx:latest

bind mount

特徴

  • ホスト上のファイル・ディレクトリをコンテナでマウントして利用
  • ホスト上で編集OK
  • 複数コンテナで共有可能

マウント方法(-vオプションを使う場合)

  • カレントディレクトリにsourceディレクトリを作成しつつマウントする例
    docker run -itd --name bind-test1 -v `pwd`/source:/app nginx

マウント方法(--mountオプションを使う場合。推奨)

  • volumeマウントと同様--mountオプションを使用するが、type=bindを追加で指定する
    docker run -itd --name bind-test2 --mount type=bind,source=`pwd`/source2,target=/app nginx
  • mountオプションは存在しないディレクトリは指定できない。安全

tmpfs


特徴

  • ホスト上のメモリ領域をコンテナのディレクトリとしてマウント

マウント方法

  • --mountオプションで、type=tmpfsを指定する。
  • 下記は、tmpfsのサイズを500MB、パーミッションを700で作成するケース
    docker run --name tmpfs-test2 -itd --mount type=tmpfs,target=/app,tmpfs-size=500M,tmpfs-mode=700 nginx

Network

ホストと同じネットワーク構成にする(hostネットワーク)

  • hostネットワークに接続してコンテナ起動すると、ホストのIPで接続できる(-pオプションでのポート転送が不要になる)
    docker run --name web --network host -d nginx
  • 上記例だとホストIPの80番ポートでNginxに接続できる

コンテナ間接続(ユーザ定義ブリッジを作成)(推奨)

  • デフォルトでは、コンテナはbridgeに接続される。
    $ docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    bb5b7794ad0c        bridge              bridge              local  # デフォルトで接続されるブリッジ
    5e2bab059a7b        host                host                local
    8c7bbdb81758        none                null                local  # loopbackしか持たないブリッジ。
  • 上記デフォルトブリッジに接続した場合、コンテナ同士はIP指定で接続できるが、コンテナ名指定では接続不可
  • コンテナ名で接続するには、ユーザ定義ブリッジを作成して、それに接続させる必要がある。以下その手順。
  • ブリッジ作成
    docker network create <ブリッジ名>
  • 作成したブリッジにコンテナを接続させる
    docker network connect <作成したブリッジ名> <コンテナ名>
  • コンテナ起動時にブリッジ接続させる方法
    docker run --name alpine3 -itd --network <ブリッジ名> <コンテナ名>
  • デフォルトブリッジとコンテナの接続を解除する方法
    docker network disconnect bridge <コンテナ名>

ノンネットワーク(コンテナ間接続させない)

  • ノンネットワークブリッジに接続させる
    docker run -itd --network none <コンテナ名>

コンテナ間接続(linkオプションを使う)

docker run --name from-srv -d --link <リンク先コンテナ名[:エイリアス]> my-proxy
  • link自体は古く、通常はdockerネットワークを作成することで接続させるのが主流
  • linkは後述のlink先の環境変数をlink元でも自動設定できるので、そのような用途が必要な場合に利用するとよい
  • サンプル。reverse-proxyコンテナが、static-siteコンテナに接続できるようにリンク設定する場合
    docker run --name reverse-proxy -d -p 80:8080 --link static-site:ss reverse-proxy
    • reverse-proxyコンテナにログインすると、以下のような設定がされている
      root@642d0d8ad35f:/# cat /etc/hosts | grep ss
      172.17.0.3      ss 1778e260b0b9 static-site
      
      root@642d0d8ad35f:/# env | grep SS
      SS_PORT=tcp://172.17.0.3:80
      SS_ENV_AUTHOR=44maru san     # link先に設定した環境変数(AUTHOR)もlink元で設定される
      SS_PORT_80_TCP_ADDR=172.17.0.3
      SS_ENV_NGINX_VERSION=1.9.12-1~jessie
      SS_PORT_443_TCP=tcp://172.17.0.3:443
      SS_PORT_443_TCP_PROTO=tcp
      SS_PORT_443_TCP_PORT=443
      SS_PORT_80_TCP=tcp://172.17.0.3:80
      SS_PORT_80_TCP_PORT=80
      SS_NAME=/reverse-proxy/ss
      SS_PORT_80_TCP_PROTO=tcp
      SS_PORT_443_TCP_ADDR=172.17.0.3
      

コンテナへのシェル接続

  • コンテナ起動
    docker run --name connect-test -it -d ubuntu /bin/bash
  • atachコマンドでの接続
    docker attach connect-test
    • コンテナを停止せずにデタッチするには、Ctrl-P、Ctrl-Qと続けて入力。exitはコンテナも停止する
  • execコマンドでの接続
    docker exec -it connect-test /bin/bash
    • exitしてもコンテナは停止しない

コンテナ・ホスト間のファイルコピー

  • ホスト→コンテナ
    docker cp <ホスト上のファイルパス> <コンテナ名|コンテナID>:<コピー先パス>
  • コンテナ→ホスト
    docker cp <コンテナ名|コンテナID>:<コピーしたいファイルパス> <ホスト上のコピー先パス>

コンテナ・イメージの削除

  • イメージを消すためには先にコンテナを消す必要がある

コンテナ削除

  • コンテナ削除
    docker rm <コンテナID|コンテナ名> # 複数ID指定可能
    • コンテナID・コンテナ名確認方法
      docker ps -a 
      CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
      6d9134dc21a4        hello-world         "/hello"            35 minutes ago      Exited (0) 35 minutes ago                       gifted_heyrovsky
  • 一括削除方法
    docker rm `docker ps -a -q`
    • docker ps -a -qはコンテナIDをリスト表示するコマンド
       docker ps -a -q
      6d9134dc21a4
      948423d3c034

イメージ削除

  • 以下のコマンドで削除
    docker rmi <イメージ名[:タグ名] またはイメージID>
    • イメージ一覧
      docker images
  • コンテナを削除していないとエラーになる。-fオプションを付ければ強制的に消せるが、コンテナは残ったままとなる
    docker rmi -f <イメージ名[:タグ名] またはイメージID>

Dockerfile

  • Dockerfile サンプル
    FROM docker/whalesay
    
    RUN apt-get -y update && apt-get -y install fortunes
    
    CMD /usr/games/fortune | cowsay
  • ビルドコマンド(-tオプションはイメージ名(タグ名)指定)
    docker build -t docker-whale .

docker-machine

docker-compose