20200730のdockerに関する記事は17件です。

Laradock + Apache のDocumentRootの設定でハマった

先日、LaradockでLaravelの開発環境を構築しました。

サーバはapache2にしたのですが、nginxでは出なかったエラーにハマったのでメモ書き。

とりあえず普通に構築

最初の設定はこんな感じ

laradock/.env
APP_CODE_PATH_HOST=../laravelproject
APP_CODE_PATH_CONTAINER=/var/www/

<中略>

APACHE_HOST_HTTP_PORT=800
APACHE_DOCUMENT_ROOT=/var/www/public
laradock/apache2/Dockerfile
FROM webdevops/apache:centos-7
laradock/apache2/sites/default.apache2.conf
<VirtualHost *:80>
  ServerName servername.test
  DocumentRoot /var/www
  Options Indexes FollowSymLinks

  <Directory "/var/www/">
    AllowOverride All
    <IfVersion < 2.4>
      Allow from all
    </IfVersion>
    <IfVersion >= 2.4>
      Require all granted
    </IfVersion>
  </Directory>

</VirtualHost>

この設定で/var/www/直下にlaravelprojectが展開され、DocumentRootがpublicになると思いました。

エラー

「このサイトにアクセスできません」画面で接続できない。

ログを確認

$ docker logs -f laradock_apache2_1

無限にエラー出てる

2020-07-30 13:08:44,418 INFO spawned: 'apached' with pid 23
-> Executing /opt/docker/bin/service.d/httpd.d//10-init.sh
2020-07-30 13:08:44,507 INFO success: apached entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)  
AH00526: Syntax error on line 119 of /etc/httpd/conf/httpd.conf:
DocumentRoot '/var/www/html' is not a directory, or is not readable
2020-07-30 13:08:44,659 INFO exited: apached (exit status 1; not expected)

DocumentRootの/var/www/htmlがない?
設定が反映されていないのだろうか。

処置

とりあえず動く状態を目指す

laradock/.env
APP_CODE_PATH_HOST=../laravelproject
APP_CODE_PATH_CONTAINER=/var/www/project

<中略>

APACHE_HOST_HTTP_PORT=800
APACHE_DOCUMENT_ROOT=/var/www/project/public
laradock/apache2/sites/default.apache2.conf
<VirtualHost *:80>
  ServerName servername.test
  DocumentRoot /var/www/project/public
  Options Indexes FollowSymLinks

  <Directory "/var/www/project/public/">
    AllowOverride All
    <IfVersion < 2.4>
      Allow from all
    </IfVersion>
    <IfVersion >= 2.4>
      Require all granted
    </IfVersion>
  </Directory>

</VirtualHost>
$ docker-compose down 
$ docker-compose build apache2
$ docker-compose up -d apache2

http://localhost:800/にアクセスしたら無事いつものLaravel画面が。

まとめ

いろいろ調べたけど、原因がいまいち掴めず。
もっといい方法があれば知りたい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

事前にデータ投入をしたMySQL Docker containerを作成したいが、/docker-entrypoint-initdb.dで毎回実行時にimportするには時間がかかりすぎる。予めimageに含めてしまおう。

事前にデータが投入されたMySQLのDocker containerを作る方法はMySQL | Docker Hubに書かれているように、

Initializing a fresh instance
When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.

/docker-entrypoint-initdb.dにsqlファイルをおいておけば実行時によしなにimportしてくれる。

ただ、自分のプロジェクトでは大きめのsqlをimportする必要があり、実行時にimportするのでは時間がかかりすぎるので、予めimageにimportしておくことにした。

Dockerfile
FROM mysql:5.7

COPY test.sql /tmp/
RUN /bin/bash -c "/usr/bin/mysqld_safe --skip-grant-tables &" \
  && sleep 5 \
  && mysql -u root -e "CREATE DATABASE test" \
  && mysql -u root test < /tmp/test.sql \
  && rm -rf /tmp/test.sql

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker コンテナを構築して altair から png 保存する

私は長い試行錯誤を要したので成果だけでもアップしておく。chromedriver-binary の最新版を入れたら google-chrome-stable よりメジャーバージョンが大きくてエラーが出た。Chrome 側で stable 以外を使ってもよさそうだが、Chrome に chromedriver-binary を合わせることにした。

Dockerfile
FROM python

# Chrome のインストール
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add && \
    echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list && \
    apt update && apt install -y google-chrome-stable

WORKDIR /python
COPY requirements.txt .
# chromedriver-binary のメジャーバージョンを Chrome に合わせる
#     google-chrome --version: "Google Chrome 0.0.0.0" のような文字列を返す
#     grep --only-matching:    (各行で) マッチした部分のみを順にすべて返す
#     head -n 1:               メジャーバージョンだけとってくる
#     sed --in-place:          私は知らなかった
RUN sed -e s/chromedriver-binary/chromedriver-binary==`google-chrome --version | grep -o -E "[0-9]*" | head -n 1`.*/ -i requirements.txt

RUN pip install --upgrade pip && pip install -r requirements.txt
requirements.txt
altair
altair_saver
chromedriver-binary
jupyter
matplotlib
numpy
pandas
scipy==1.5
selenium

タイトルに関係あるのは altair, altair_saver, chromedriver-binary, selenium のはず。

main.py
import altair
import chromedriver_binary              # import によって PATH が通る; モジュールとしては使わない
altair.renderers.enable('altair_saver') # 公式ドキュメントにはフォーマットを指定する引数があったが、怒られたので外した
altair.Chart(...).....save('plot.png')  # 成功した
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-compose run とか打ち込むのめちゃくちゃめんどくさいなと思ってる人へ。

dockerとRailsで環境構築しているのですが、いちいち
docker-compose run app rails g controller ....
とか打つのめんどくさいですよね?
エイリアスを設定すればこの問題を解決できます!

エイリアスとは?

元々エイリアスというのは偽物とか、別名などの意味を持つ英単語です。

エイリアスを設定するということは、コマンドに別名を設定することができるということです。例えば

docker-compose runを略してdcrとかに設定できます。

設定方法

1.ホームディレクトリに.bashrcというファイルを作る。

.bashrcというのはbashを起動したときに読み込まれる設定ファイルのことです。

2..bashrcにエイリアスを定義する

.bashrcに以下のように記述していきます。
(以下は僕が使っている設定です。)

#dockerのエイリアス
alias d='docker'
alias dc='docker-compose'
alias dcb='docker-compose build'
alias dcps='docker-compose ps'
alias dcud='docker-compose up -d'
alias dcex='docker-compose exec'
alias dcd='docker-compose down'
alias dcl='docker-compose logs'

#Gitのエイリアス
alias gb='git branch'
alias gc='git checkout'
alias gcb='git checkout -b'
alias gs='git status'
alias gco='git commit'
alias gp='git push'
alias ga='git add'
alias gl='git log'
alias gcd='git checkout development'
alias gpod='git pull origin development'
alias gmd='git merge origin development'
alias git delete-merged-branch='!f () { git checkout $1; git branch --merged|egrep -v '\*|develop|master'|xargs git branch -d; };'

3..bash_profileに.bashrcを読み込ませる

.bash_profileというのはログインシェルがbashの状態でログインしたときに読み込まれる設定ファイルのことです。
.bash_profileの一番下に以下のように記述して設定を読み込ませます。

source ~/.bashrc

その後、ターミナルでsource ~/.bashrcを実行し、ターミナルを再起動してください。

以上で設定は完了になります。実際に設定できているかターミナルで確認してみましょう。

最後までよんでいただきありがとうございます。

もし何か誤植等ありましたら、ご指摘いただけますと幸いです。よろしくお願い致します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker導入手順

はじめに

Dockerをインストールしたので手順を記録します。

本記事ではHomebrewとGUIを使います。
また、Dockerの概念等については詳しく書かれている良記事がたくさんありますので割愛します。

環境

  • macOS Mojave 10.14.6

やったこと

ターミナルから実行

brewでインストール

$ brew install docker
$ brew cask install docker 

$ docker --version
Docker version 19.03.12, build 48a6621

caskとは、GUIをインストールするHomebrewの拡張機能です。

参考:homebrew-caskとは

アプリケーションを起動

open /Applications/Docker.app 

ダイアログが表示されます。
スクリーンショット 2020-07-30 17.01.40.png

GUIで設定する

ターミナルつきのダイアログが出てきます。
青いボタンをクリックすると、ボタン内に記述されているコマンドがターミナルで実行される仕様です。

git clone https://github.com/docker/getting-started.git
実行が終わったら「Next Step」で進みます。
スクリーンショット 2020-07-30 17.05.10.png

  • クローンしたリポジトリに移動
  • Dockerイメージを作成 docker build -t {イメージ名} スクリーンショット 2020-07-30 17.16.43.png

起動
スクリーンショット 2020-07-30 17.20.51.png

ここでサインインが必要になります。
まだアカウントを持っていない人はDockerのページで作成してください。
スクリーンショット 2020-07-30 17.22.01.png

OPEN IN BROWSERをクリックすると
スクリーンショット 2020-07-30 17.29.41.png

localhostでチュートリアルが立ち上がります。すごい。。
スクリーンショット 2020-07-30 17.30.35.png

さいごに

こちらの記事に大変助けられました。
DockerをHomebrewでMac OSに導入する方法

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker インストール手順

はじめに

Dockerをインストールしたので手順を記録します。

本記事ではHomebrewとGUIを使います。
また、Dockerの概念等については詳しく書かれている良記事がたくさんありますので割愛します。

環境

  • macOS Mojave 10.14.6

やったこと

ターミナルから実行

brewでインストール

$ brew install docker
$ brew cask install docker 

$ docker --version
Docker version 19.03.12, build 48a6621

caskとは、GUIをインストールするHomebrewの拡張機能です。

参考:homebrew-caskとは

アプリケーションを起動

open /Applications/Docker.app 

ダイアログが表示されます。
スクリーンショット 2020-07-30 17.01.40.png

GUIで設定する

ターミナルつきのダイアログが出てきます。
青いボタンをクリックすると、ボタン内に記述されているコマンドがターミナルで実行される仕様です。

git clone https://github.com/docker/getting-started.git
実行が終わったら「Next Step」で進みます。
スクリーンショット 2020-07-30 17.05.10.png

  • クローンしたリポジトリに移動
  • Dockerイメージを作成 docker build -t {イメージ名} スクリーンショット 2020-07-30 17.16.43.png

起動
スクリーンショット 2020-07-30 17.20.51.png

ここでサインインが必要になります。
まだアカウントを持っていない人はDockerのページで作成してください。
スクリーンショット 2020-07-30 17.22.01.png

OPEN IN BROWSERをクリックすると
スクリーンショット 2020-07-30 17.29.41.png

localhostでチュートリアルが立ち上がります。すごい。。
スクリーンショット 2020-07-30 17.30.35.png

ここからはそれぞれ必要なイメージを追加していくことになるので
それはまた別の記事にまとめられたらと思います。

さいごに

こちらの記事に大変助けられました。
DockerをHomebrewでMac OSに導入する方法

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Raspberry PiでDockerを使ってみた

Raspberry PiでDockerを使ってみた備忘録
以下を参照
https://docs.docker.com/engine/install/debian/

環境

Raspberry Pi 4B(メモリ4GB)
Raspberry Pi OS 10.4

インストール

インストールして、ユーザー権限を付与します。
その後、再起動。

$ curl -sSL https://get.docker.com/ | sh
$ sudo usermod -aG docker pi
$ sudo systemctl isolate reboot.target

コンテナの起動

再起動後、dockerが動作するか確認します。

$ docker -v
Docker version 19.03.12, build 48a6621
$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm32v7)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

dockerの自動起動の設定

$ sudo systemctl enable docker
Synchronizing state of docker.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable docker
$ systemctl is-enabled docker
enabled

次に、以下を実行してubuntuコンテナを起動してみます。

docker run -it ubuntu bash
-iはコンテナの標準入力に接続するオプション
-tはターミナルを割り当てるオプション

コンテナ名を指定する場合は、--nameオプションを使用。
指定しないとランダムな名前が割り当てられるようです。

初回はイメージの取得に時間を要します。

$ docker run -it ubuntu bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
86924fd76ad7: Pull complete
8e967235e6ad: Pull complete
fabf100c8ea1: Pull complete
344cec738d22: Pull complete
Digest: sha256:5d1d5407f353843ecf8b16524bc5565aa332e9e6a1297c73a92d3e754b8a636d
Status: Downloaded newer image for ubuntu:latest
root@6426a92ad57c:/# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   2716  2148 pts/0    Ss    2020   0:00 bash
root        11  0.0  0.0   4376  1744 pts/0    R+    2020   0:00 ps aux

コンテナを終了するときは、コンテナ内でexitを実行します。

root@6426a92ad57c:/# exit
exit
pi@raspberrypi:~ $

取得したイメージは、dockerのimagesコマンドを使用して確認できます。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              014028cfedab        5 days ago          50.7MB
hello-world         latest              851163c78e4a        6 months ago        4.85kB

2回目以降の起動時は高速

$ docker run -it ubuntu bash
root@0cb3b5aab220:/#

コンテナを終了せずに抜ける時は、CTRL+P CTRL+Qを押下。

root@0cb3b5aab220:/# pi@raspberrypi:~ $

再度接続する時は、dockerのattachコマンドを使用。
今回はコンテナIDを指定して接続。
コンテナIDは一部の指定だけでも良いようです。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
0cb3b5aab220        ubuntu              "bash"              About a minute ago   Up About a minute                       festive_lamarr
$ docker attach 0cb3
root@0cb3b5aab220:/#                   

コンテナの再開

再開させるには、dockerのstartコマンドを使用。
終了させるには、dockerのstopコマンドを使用。

root@0cb3b5aab220:/# exit
exit
$ docker ps -a
CONTAINER ID        IMAGE                COMMAND               CREATED             STATUS                      PORTS               NAMES
0cb3b5aab220        ubuntu               "bash"                18 minutes ago      Exited (0) 10 seconds ago                       festive_lamarr
$ docker start 0cb3
0cb3
$ docker ps -a
CONTAINER ID        IMAGE                COMMAND               CREATED             STATUS                      PORTS               NAMES
0cb3b5aab220        ubuntu               "bash"                23 minutes ago      Up 11 seconds                                   festive_lamarr
$ docker stop 0cb3
0cb3
$ docker ps -a
CONTAINER ID        IMAGE                COMMAND               CREATED             STATUS                      PORTS               NAMES
0cb3b5aab220        ubuntu               "bash"                24 minutes ago      Exited (0) 2 seconds ago                        festive_lamarr
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerコンテナのリソース制限機能を使った実践的な体験談 その1

このチュートリアルでは、Alibaba Cloud ECS上でDockerコンテナのリソース制限機能を利用した実践的な体験ができます。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

前提条件

最新バージョンのDockerがすでにインストールされているECSサーバーにアクセスする必要があります。もしまだ持っていない場合は、このチュートリアルの手順に従ってください。

これらのリソース制限テストでは20~30MBのRAMを使用するので、合計512MBのRAMしかないサーバでも問題ありません。

CPUテストは2コアのみのサーバで行われます。サーバーのコア数が 4 つ以上の場合、テストの一つとして、より興味深い結果が得られるでしょう。

いくつかの CPU テストでは、15 秒間すべての CPU を占有します。このチュートリアルを共有開発サーバではなく、あなたのコンピュータで直接行った方が、あなたのチームメイトのためにも良いでしょう。

私はCentOSを使ってこのチュートリアルを書いています。Debian / Ubuntuを使用することができます。このチュートリアルは主にDockerコマンドを使用しているので、99%はどのLinuxディストロでも動作します。

Docker、イメージ、コンテナ、そしてdocker runとdocker ps -aの使用については、非常に基本的な理解が必要です。

クリーンアップの準備

実行中のコンテナーが少ない(できればない)場合に非常に役立ちます。このようにすると、Docker ps -a出力リストでチュートリアルコンテナーを簡単に見つけることができます。

そこで、実行している必要のないすべてのコンテナを停止してプルーニングしてください。

(開発環境で)次のようにしてすばやく実行できます。

docker stop $(docker ps -a -q) #stop ALL containers

すべてのコンテナを削除するには、次のように実行します。

docker rm -f $(docker ps -a -q) # remove ALL containers

––memory-reservation

https://docs.docker.com/config/containers/resource_constraints/ より

メモリ不足や競合をDockerが検知したときに起動する--memoryよりも小さいソフトリミットを指定することができます。もし --memory-reservation を使用する場合は --memory よりも小さい値を設定しなければ優先されません。ソフトリミットなので、コンテナがリミットを超えないことを保証するものではありません。

私はこれを1GB RAMのサーバーで実行しています。

5つのコンテナをそれぞれ250MBのRAMを確保して実行してみましょう。

docker container run -d --memory-reservation=250m --name mymem1 alpine:3.8 sleep 3600
docker container run -d --memory-reservation=250m --name mymem2 alpine:3.8 sleep 3602
docker container run -d --memory-reservation=250m --name mymem3 alpine:3.8 sleep 3603
docker container run -d --memory-reservation=250m --name mymem4 alpine:3.8 sleep 3604
docker container run -d --memory-reservation=250m --name mymem5 alpine:3.8 sleep 3605

私は250 MBのRAMを過剰予約したにもかかわらず、すべてのコンテナが実行されています。つまり、これは絶望的です: そして、過剰予約を防ぐことはできません。

topを実行すると、仮想RAMが割り当てられていないことがわかります。この設定はDockerの内部です。

 PID USER        VIRT    RES    SHR S %MEM     TIME+ COMMAND
  933 root      967.4m  86.0m  24.3m S  8.7   0:55.87 dockerd
  940 root      582.0m  36.3m  12.3m S  3.7   0:46.50 docker-containe
13422 root        8.7m   3.3m   2.5m S  0.3   0:00.02 docker-containe
13309 root        7.3m   3.0m   2.3m S  0.3   0:00.02 docker-containe
13676 root        7.3m   2.9m   2.2m S  0.3   0:00.01 docker-containe
13540 root        7.3m   2.8m   2.1m S  0.3   0:00.01 docker-containe
13793 root        8.7m   2.7m   2.1m S  0.3           docker-containe

docker stats は RAM の予約状況を表示しません。

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
a1a4bd1c226b        mymem5              0.00%               1.086MiB / 985.2MiB   0.11%               578B / 0B           1.19MB / 0B         0
9ced89c63a7e        mymem4              0.00%               1.105MiB / 985.2MiB   0.11%               648B / 0B           1.19MB / 0B         0
696f1cef7d57        mymem3              0.00%               1.113MiB / 985.2MiB   0.11%               648B / 0B           1.19MB / 0B         0
77d61012b5fd        mymem2              0.00%               1.086MiB / 985.2MiB   0.11%               648B / 0B           1.19MB / 0B         0
fab3faa6d23d        mymem1              0.00%               1.043MiB / 985.2MiB   0.11%               648B / 0B           1.19MB / 0B         0
docker ps -a

5つのコンテナが正常に動作していることを表示します。

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a1a4bd1c226b        alpine:3.8          "sleep 3605"        2 minutes ago       Up 2 minutes                            mymem5
9ced89c63a7e        alpine:3.8          "sleep 3604"        4 minutes ago       Up 4 minutes                            mymem4
696f1cef7d57        alpine:3.8          "sleep 3603"        5 minutes ago       Up 5 minutes                            mymem3
77d61012b5fd        alpine:3.8          "sleep 3602"        6 minutes ago       Up 6 minutes                            mymem2
fab3faa6d23d        alpine:3.8          "sleep 3600"        8 minutes ago       Up 8 minutes                            mymem1

これらのコンテナは終了しました。止めてからプルーニングすればいいのです。

docker container stop mymem1 -t 0
docker container stop mymem2 -t 0
docker container stop mymem3 -t 0
docker container stop mymem4 -t 0
docker container stop mymem5 -t 0
docker container prune -f 

--memory and --memory-swap (スワップ不可)

https://docs.docker.com/config/containers/resource_constraints/ より

  • -m または --memory= コンテナが使用できる最大メモリ量。このオプションを設定した場合、最小許容値は 4m (4 メガバイト) です。
  • --memory-swap このコンテナがディスクにスワップすることを許可するメモリの量です。
  • memory-swap が --memory と同じ値に設定され、 --memory が正の整数に設定されている場合、コンテナはスワップにアクセスできません。 現在、スワップを許可しないことをテストしています。

慎重にMB単位でRAMを割り当てるためのツールが必要です - そうすれば、定義されたRAMの限界を慎重に超えてしまうだけです。私はPythonに決めました。( ここで使用されている4行のコードを理解するためにPythonを知る必要はありません。)

このチュートリアルの後編では、実際のベンチマークツールを使用します。

PythonのDockerイメージをまだお持ちでない方はダウンロードしてください。

docker pull python:3-alpine 

コンテナを実行し、RAMを制限: --memory=20m --memory-swap=20m

docker container run -d --memory=20m --memory-swap=20m --name myPython python:3-alpine sleep 3600
docker exec -it myPython /bin/sh  

シェルプロンプトでpython3と入力して、対話型のPythonエディタに入ります。以下のコードをカットアンドペーストしてください。Pythonではスペースには構文上の意味があるので、スペースやタブを追加しないように注意してください。

longstring = []
for x in range(17):
    len(longstring)
    longstring.append('1' * 10**6)

Enterキーを押してステートメントブロックを終了します。これでコードが実行されます。

期待される出力 .

>>> for x in range(17):
...     len(longstring)
...     longstring.append('1' * 10**6)
...
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Killed

このコンテナに20MBのRAMを割り当てました。Python は 5 MB を使用しています。forループは16MBの'1'文字をlongstring変数に追加しようとするとkillされてしまいます。

3つの注意点があります。

  • 20 MB の制限内で RAM を割り当てた場合は動作しました。
  • 制限を超えたRAMの割り当ては強制終了しました。
  • スワップを使用しない:スワップを使用することで、割り当てが静かに動作を継続しませんでした。

要約: --memory と --memory-swap (スワップは許可されていません) は両方とも同じ値に設定されている場合に動作します。コンテナ内で実行されているアプリケーションの知識に基づいて、これらの値を適切に設定する必要があります。

これでこのコンテナは終了です。これでこのコンテナは終了です。

docker container stop myPython
docker container prune -f 

––memory and --memory-swap (スワップ可能)

memory=20m と --memory-swap=30m を指定すると、10MBのスワップが可能になります。

どのように動作するか見てみましょう。

docker container run -d --memory=20m --memory-swap=30m --name myPython python:3-alpine sleep 3600

docker exec -it myPython /bin/sh             

シェルプロンプトでpython3と入力して、インタラクティブなPythonエディタを起動します。以下のコードをカットアンドペーストしてください。Pythonではスペースには構文上の意味があるので、スペースやタブを追加しないように注意してください。

longstring = []
for x in range(24):
    len(longstring)
    longstring.append('1' * 10**6)

ENTERを押してfor文ブロックを終了します。これでコードが実行されます。

期待される出力 .

0 to 24 shown ... no killing

Pythonが使用する5MBのRAM。上記のように25MBのRAMを確保していますが、エラーはありません。

メモリ=20m --メモリスワップ=30mを指定しています。

30MBを使っただけなので、10MBがスワップされていることになります。topを別のシェルで実行して確認してみましょう。

top - 13:20:38 up  4:41,  2 users,  load average: 0.11, 0.05, 0.06
Tasks: 119 total,   1 running, 118 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.2 us,  0.3 sy,  0.0 ni, 99.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  985.219 total,  466.879 free,  190.812 used,  327.527 buff/cache
MiB Swap: 1499.996 total, 1490.078 free,    9.918 used.  618.730 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND             SWAP
  933 root      20   0  967.4m  91.5m  24.3m S        9.3   0:45.46 dockerd
  940 root      20   0  579.9m  33.1m  12.3m S   0.3  3.4   0:36.73 docker-containe
11900 root      20   0  253.5m  19.1m  10.5m S        1.9   0:00.25 docker
11941 root      20   0   39.1m  17.4m        S        1.8   0:00.39 python3             9.5m

予想通り、10MBのスワップが使用されています。(SWAPフィールドをトップに表示する必要があります。)

慎重に2MB以上のRAMを使うようにしましょう - コンテナはRAMを使い果たしているはずです。

これを切り取り、Pythonエディタに貼り付けます。ENTERキーを押して実行します。

longstring = []
for x in range(26):
    len(longstring)
    longstring.append('1' * 10**6)

期待される出力 .

it gets killed

このコンテナが完成しました。停止してプルーニングすることができます。

docker container stop myPython
docker container prune -f 

概要: --memoryと--memory-swap (スワップ可能)は--memory-swapが--memoryよりも大きい場合に動作します。

制限は完全に適用されます。

本番環境ではコンテナに適切な制限を指定する必要があります。

現在のprodシステムのRAM使用量を調査してください。それに応じて制限値を定義することで、エラーの可能性を大きく広げながらも、暴走したコンテナがprodサーバをクラッシュさせるのを防ぎます。

--ooom-kill-disable

これまでのところ、自動的に有効になったアウトオブメモリ機能は、私たちの暴走するPythonプログラムをkillしてしまいました。

これを無効にするとどうなるか見てみましょう。

以下の --oom-kill-disable に注意してください。

docker container run -d --oom-kill-disable --memory=20m --memory-swap=30m --name myPython python:3-alpine sleep 3600

無防備なコンテナに入力してください。

docker exec -it myPython /bin/sh   

python3エディタを入力し、そのコードを貼り付け、ENTERを押して実行します。

python3    
a = []
for x in range(26):
    len(a)
    a.append('1' * 10**6)

コンテナがハングします。

別のシェルコンソールで top を実行します。

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND             SWAP
12317 root      20   0   41.0m  17.6m   0.0m D        1.8   0:00.32 python3            10.7m

コンテナの状態は D : uninterruptible sleep

別のシェルでは

docker exec -it myPython /bin/sh  

これもハングします。

別のシェルを使用して、ぶら下がっているコンテナのPIDを取得して、強制終了できるようにします。

docker inspect myPython

PIDを取得します。

topかkill -9 your-PIDを使用して、それを強制終了します。。

結論:
ooom-kill-disableは使用しないでください。

あなたのハングアップしたシェルは、Linuxプロンプトに戻っています。これらを終了することができます。

––cpu-shares

https://docs.docker.com/config/containers/resource_constraints/#cpu より

--cpu-share. このフラグをデフォルトの1024よりも大きいか小さい値に設定することで、コンテナの重量を増減させ、ホストマシンのCPUサイクルの大きいか小さいかの割合でアクセスできるようにします。
これは、CPU サイクルが制限されている場合にのみ適用されます。多くのCPUサイクルが利用可能な場合、すべてのコンテナは必要なだけのCPUを使用します。これはソフトリミットです。--cpu-sharesは、スウォームモードでコンテナがスケジューリングされるのを防ぐものではありません。
利用可能なCPUサイクルに対してコンテナのCPUリソースを優先します。特定のCPUアクセスを保証したり予約したりするものではありません。

計画:100、500、1000のCPUシェアを提供する3つのコンテナを実行します。

以下はひどいテストです。上記の説明をもう一度注意深く読んでから、次の3つのコマンドを読んで、なぜ正しく割り当てられたCPUの割合が明確に表示されないのかを判断できるかどうかを確認してください。

これらの CPU テストは、あなたが自分のコンピュータでこれを実行していて、共有開発サーバではないと仮定していることに注意してください。3つのテストでは、20秒間100%のCPUを占有します。

このチュートリアルシリーズの後半では、実際の Linux ベンチマークツールを使用して、独自のベンチコンテナを使用してこれらのテストを行います。特に、これらの CPU ホッグを非常に短いランタイムで実行して、正確な結果を得ることに焦点を当てます。

しかし、これらの CPU テストを読んで、このクイックハックテストがいかに間違っていて遅いかを知ってください。

dd, urandom, md5sum はベンチツールではないことに注意してください。

問題はddやそのタイミングではありません。

CPUストレスアプリケーション: time dd if=/dev/urandom bs=1M count=2 | md5sum

ベンチマークの説明:

  • time ... 経過時間を測定します。
  • dd if=/dev/urandom bs=1M count=2 ... copies bs=blocksize 1MBのランダム性を2回繰り返す
  • md5sum ... md5セキュリティハッシュを計算 (CPUに負荷を与える)

実行して結果を調べてみましょう。

docker container run -d --cpu-shares=1024 --name mycpu1024 alpine:3.8 /bin/sh -c 'time dd if=/dev/urandom bs=1M count=100 | md5sum'
docker container run -d --cpu-shares=500 --name mycpu500 alpine:3.8 /bin/sh -c 'time dd if=/dev/urandom bs=1M count=100 | md5sum'
docker container run -d --cpu-shares=100 --name mycpu100 alpine:3.8 /bin/sh -c 'time dd if=/dev/urandom bs=1M count=100 | md5sum'

ランタイムを判断するためにログを調査してみましょう。

docker logs mycpu1024
docker logs mycpu500
docker logs mycpu100

期待される出力:

docker logs mycpu1024
real    0m 15.29s
user    0m 0.00s
sys     0m 14.51s

docker logs mycpu500
real    0m 18.65s
user    0m 0.00s
sys     0m 15.28s

docker logs mycpu100
real    0m 23.28s
user    0m 0.00s
sys     0m 13.09s

すべてのコンテナがほぼ同じ sys cpu 時間を使用していることに注意してください。

--cpu-shares=100 は明らかに時間がかかりますが、 --cpu-shares=500 は --cpu-shares=1024 よりもわずかに遅くなります。

問題は --cpu-shares=1024 が非常に高速に動作した後に終了してしまうことです。

すると、--cpu-shares=500と--cpu-shares=100がCPUをフルに利用できるようになります。

すると--cpu-shares=500はほとんどのCPUを占有しているので、すぐに終了します。

そして、--cpu-shares=100は、ほとんどのCPUのシェアを持っているので、すぐに終了します - 他には何も動いていません。

この問題とその解決方法を考えてみてください。

これ以上読む前に解決策を考えてみてください。

そしてあなたの解決策を試してみてください。

解決策:

これら3つのコンテナはすべて常時並列に動作しなければなりません。CPUシェアはCPUがストレスを受けているときにのみ動作します。

mycpu1024 - カウントは mycpu100 の 10 倍に設定する必要があります。
mycpu500 - カウントはmycpu100の5倍に設定する必要があります。

このようにして、3つのコンテナの実行時間はほぼ同じになります - CPUシェアに基づいて、CPUシェアに応じた似たような作業量になります。

次に、mycpu1024の実行時間を10で割ってみると、mycpu100の10倍のワークロードが得られます。
そして、mycpu500のランタイムを5で割ってみると、 mycpu100の10倍のワークロードが得られました。

DockerがCPUシェアを適当に分けたのは、ごくごく当たり前のことのはずです。

忙しいDocker管理者のショートカット/クイックメソッド:

上記のコンテナを全て提出して再度実行する。
以下も実行できるように準備しておきましょう。

--cpu-shares=250 and --cpu-shares=200 containers

次に別のシェルで docker stats を実行して ctrl c を押して表示をフリーズさせます。

CPUシェアが正しく割り当てられていることは明らかです。

コンテナをクリーンアップします:

docker container prune -f 

同一に割り当て --cpu-share

--cpu-share. このフラグを設定すると、コンテナの重量を増やしたり減らしたりして、ホストマシンのCPUサイクルの割合を増やしたり減らしたりします。

これは、CPU-sharesが同じに設定されていると、CPUの占有率が同じになることを意味します。

3つのコンテナを実行していて、すべてのコンテナのCPUシェアが1024であるとします。

docker container run -d --cpu-shares=1024 --name mycpu1024a alpine:3.8 /bin/sh -c 'time dd if=/dev/urandom bs=1M count=100 | md5sum'
docker container run -d --cpu-shares=1024 --name mycpu1024b alpine:3.8 /bin/sh -c 'time dd if=/dev/urandom bs=1M count=100 | md5sum'
docker container run -d --cpu-shares=1024 --name mycpu1024c alpine:3.8 /bin/sh -c 'time dd if=/dev/urandom bs=1M count=100 | md5sum'

実行:

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
c4625617f339        mycpu1024c          63.79%              1.262MiB / 985.2MiB   0.13%               648B / 0B           1.33MB / 0B         0
44362316e33a        mycpu1024b          68.44%              1.254MiB / 985.2MiB   0.13%               648B / 0B           1.33MB / 0B         0
a704aca5c0d7        mycpu1024a          66.27%              1.254MiB / 985.2MiB   0.13%               648B / 0B           1.35MB / 0B         0

予想通り、3つのコンテナはすべて同じ割合のCPU時間を取得します。

docker logs mycpu1024a
docker logs mycpu1024b
docker logs mycpu1024c

すべてが同じ経過時間を実行したことを確認するだけです。

docker logs mycpu1024a
real    0m 21.25s
user    0m 0.00s
sys     0m 14.72s

docker logs mycpu1024b
real    0m 22.53s
user    0m 0.00s
sys     0m 15.21s

docker logs mycpu1024c
real    0m 21.45s
user    0m 0.00s
sys     0m 15.09s

プルーンコンテナ、終了です。

docker container prune -f 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Kubernetes] Kind (Kubernetes in Docker) を試してみた

Kind とは?

  • Docker 上で Kubernetes を動かすもの
  • Kubernetes の各ノードはコンテナとして動く
  • 構築が非常に楽(ほぼワンライナー)
  • コンテナが動くだけなので環境を汚さない
  • 使い捨てしやすいので学習に適している
  • etc...

今回の環境

  • Ubuntu Server 20.04 on VMware ESXi

いざ挑戦

Kind の入手

シングルバイナリで公開されているのでダウンロードして配置します。

$ curl -L -o kind https://github.com/kubernetes-sigs/kind/releases/download/v0.8.1/kind-$(uname)-amd64
$ sudo chmod +x kind
$ sudo mv kind /usr/bin/kind
$ kind version
kind v0.8.1 go1.14.2 linux/amd64

Kubectl の入手

これもシングルバイナリで公開されているのでダウンロードして配置します。

$ curl -L https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
$ sudo chmod +x kubectl
$ sudo mv kubectl /usr/bin/kubectl
$ kubectl version --short --client
Client Version: v1.18.6

Kind で構築

Kind 用の設定ファイルを作成します。
今回は コントロールプレーン *1ワーカーノード *3 で構築します。

kind.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker

作成した設定ファイルを Kind に食わせて構築させます。

$ kind create cluster --config kind.yaml
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.18.2) 🖼 
 ✓ Preparing nodes 📦 📦 📦 📦  
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹️ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
 ✓ Joining worker nodes 🚜 
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Not sure what to do next? 😅  Check out https://kind.sigs.k8s.io/docs/user/quick-start/

少々待つと完了します。
kubectlKind で作った Kubernetes に向けるために設定します。

$ kubectl cluster-info --context kind-kind
Kubernetes master is running at https://127.0.0.1:34841
KubeDNS is running at https://127.0.0.1:34841/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

動作確認

実際に構築されたものを確認してみましょう。

$ kubectl get no -o wide
NAME                 STATUS   ROLES    AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE       KERNEL-VERSION     CONTAINER-RUNTIME
kind-control-plane   Ready    master   27m   v1.18.2   172.18.0.5    <none>        Ubuntu 19.10   5.4.0-42-generic   containerd://1.3.3-14-g449e9269
kind-worker          Ready    <none>   26m   v1.18.2   172.18.0.2    <none>        Ubuntu 19.10   5.4.0-42-generic   containerd://1.3.3-14-g449e9269
kind-worker2         Ready    <none>   26m   v1.18.2   172.18.0.3    <none>        Ubuntu 19.10   5.4.0-42-generic   containerd://1.3.3-14-g449e9269
kind-worker3         Ready    <none>   26m   v1.18.2   172.18.0.4    <none>        Ubuntu 19.10   5.4.0-42-generic   containerd://1.3.3-14-g449e9269

しっかり4台動いていることが確認できました。
docker ps で実際に動いているコンテナを確認できます。

$ docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                       NAMES
8b3d0f094fa3        kindest/node:v1.18.2   "/usr/local/bin/entr…"   30 minutes ago      Up 29 minutes                                   kind-worker
2dac19ed7ef8        kindest/node:v1.18.2   "/usr/local/bin/entr…"   30 minutes ago      Up 29 minutes       127.0.0.1:34841->6443/tcp   kind-control-plane
695c6175fdd5        kindest/node:v1.18.2   "/usr/local/bin/entr…"   30 minutes ago      Up 29 minutes                                   kind-worker3
8564350b333f        kindest/node:v1.18.2   "/usr/local/bin/entr…"   30 minutes ago      Up 29 minutes                                   kind-worker2

各ノードがコンテナとして動いていることが確認できます。
コントロールプレーンだけ Kubernetes API のためにポートが開いています。

後片付け

構築が簡単なので壊すのも簡単です。

$ kind delete cluster
Deleting cluster "kind" ...

以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンテナに対して適用できるDockerコマンド25選 その2

このチュートリアルでは、コンテナに対して適用できる25のDockerコマンドを簡単にデモします。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

Docker Container Inspect

https://docs.docker.com/engine/reference/commandline/container_inspect/#description より

docker container inspect : 1 つ以上のコンテナの詳細情報を表示します。

幸いにも停止しているコンテナもInspectできるので、あとは実行するだけです。

docker container inspect mycontain

このコンテナに適用されているすべての設定の長いリストが表示されます。

上部には現在の状態が表示されています:exited.

   "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,

dead = falseであることに注意してください。これは、何か壊れたコンテナであることを示しています。終了したコンテナは再起動することができますが(上でやったように)、いつか死んだコンテナが出てきた場合、再起動できないと思います。

Dockerコンテナのcommitとexport

  • docker container commit - コンテナの変更点から新しいイメージを作成する
  • docker container export - コンテナのファイルシステムを tar アーカイブとしてエクスポートする

この2つのコマンドは用途が異なります。

  • commit: 新しいイメージを作成します。そして、このイメージをベースイメージとして使用して新しいコンテナを構築することができます。新しいコンテナは元のコンテナのクローンのようなものです。
  • export: コンテナの内容を tar アーカイブファイルとして保存します。その後、任意の Linux シェルで tar を解凍してファイルの内容を調べることができます。元のコンテナは完全に消えてしまいました。私たちが持っているのはファイルシステムだけです: 環境変数もなく、「コンテナの実行状態」という概念もありません。

概要デモ - Dockerコンテナコマンド

このチュートリアルでは、パート 1 とパート 2 で説明したいくつかの docker コンテナコマンドを使用します。

開発に追われている間に、同じ全体的なアプローチを使ってコンテナに小さな変更を加え、結果を観察することができます。

計画
フェーズ1:signals

  • シンプルなbashシグナルトラップスクリプトを書く
  • mytraps:demoイメージを作成するための短いDockerfileを書く
  • run mytraps:demo image
  • docker のログでエコー出力を監視する
  • docker kill で TERM シグナルを送信 - 結果をログで確認
  • mytraps:demoイメージを再実行
  • docker kill で INT シグナルを送信 - 結果をログで確認
  • mytraps:demoイメージを再実行
  • dockerでコンテナにアタッチ
  • ctrl-c キーを押す - ログの結果を見る
  • mytraps:demoイメージを再実行
  • docker kill で KILL シグナルを送信 - ログで結果を観察

フェーズ2:環境変数

  • run mytraps:demo image
  • docker のログでエコー出力を監視する
  • 方法 1: docker exec で環境変数を変更する - 結果をログで確認する
  • 方法 2: docker exec で環境変数を変更する - 結果をログで確認する
  • docker kill で KILL シグナルを送信 - ログで結果を観察
  • シンプルなbashシグナルトラップスクリプトを書く

ナノトラップ
そのremove-meのテキストを削除してください。Markdownは見出しがハッシュで始まるようにしなければならないので、スクリプトの最初の行は見出しとしてレンダリングされます。非常識で不条理ですが、真実です。

remove-me#!/bin/bash
function SIGINT_trap() {
  echo . . . SIGINT signal caught
  echo . . . doing SIGINT cleanup
  exit
}

function SIGTERM_trap() {
  echo . . . SIGTERM signal caught
  echo . . . doing SIGTERM cleanup
  exit
}

trap SIGINT_trap SIGINT
trap SIGTERM_trap SIGTERM

for i in `seq 1 50`; do
    sleep 1
    echo -n " . "
    echo $i
done

exit 0

14行目と15行目は、受信したsignalに基づいて関連する関数を呼び出します。

  • mytraps:demoイメージを作成するために短いDockerfileを書きます。
nano Dockerfile 

Dockerfileの内容:

FROM alpine:3.8
ENV myvar original value
COPY traps /root/
RUN chmod +x /root/traps
CMD ["/bin/sh", "/root/traps"]
  • 1行目: アルパイン3.8イメージを使用
  • 2行目: myvar 環境変数を定義して値を与える
  • 3行目: bash トラップスクリプトをコンテナ内の /root/ ディレクトリにコピーします。
  • 4行目: トラップスクリプトを実行可能にする
  • 5行目: コンテナの起動時にトラップスクリプトを実行するように定義します。

そのイメージを構築します。

docker build --tag mytraps:demo --file Dockerfile .
  • コンテナのログを監視するために2つ目のシェルコンソールを準備 2つ目のシェルを起動し、実行します。
docker container logs mycontain -f

エラーが表示されます。つまり、コンテナーはまだ開始されていません。

このステップは、シェルの履歴にそのコマンドを取得することですので、我々はすぐにそれを得ることができます。以下のようになります。

  • run mytraps:demo image

最初のシェル:

docker container run -d --name mycontain mytraps:demo
  • docker のログでエコー出力を監視

2つ目のシェル:

上矢印キーを押して前のコマンドを取得し、ENTERを押します。bashスクリプトの出力が表示されます。

  • docker kill経由でTERMシグナルを送る

最初のシェルで実行します。

docker container kill --signal 15  mycontain
  • ログで結果を見る

2つ目のシェル:

期待される出力:

...
 . 15
 . 16
 . 17
 . 18
 . 19
. . . SIGTERM signal caught
. . . doing SIGTERM cleanup

SIGTERM / 15 のシグナルをキャッチしました。 - スクリプトは SIGTERM のクリーンアップを行っています。

ログ出力も停止するようになったことに注意:シグナル処理機能を処理した後、コンテナは正常に終了しました。

テスト1が完了しました: signal TERM / 15の処理に成功しました。

  • mytraps:demo imageを再実行します...signal割り込みテスト用

前に終了したコンテナを削除します。

最初のシェルで実行します。

docker container prune -f 

コンテナを再起動します。

docker container run -d --name mycontain mytraps:demo
  • docker のログでエコー出力を監視する

2つ目のシェル:

上矢印キーを押して前のコマンドを取得し、ENTERを押します。前と同じようにbashスクリプトの出力が表示されます。

  • docker kill経由で割り込みsignalを送る

最初のシェルで実行します。

docker container kill --signal SIGINT  mycontain
  • ログで結果を見る

2つ目のシェル:

期待される出力 .

...
 . 16
 . 17
 . 18
 . 19
 . 20
. . . SIGINT signal caught
. . . doing SIGINT cleanup

SIGINT信号が捕捉されました - スクリプトはSIGINTのクリーンアップを行っています。

シグナル処理機能を処理した後、コンテナは正常に終了しました。

テスト2完了: シグナルSIGINT / 2の処理に成功しました。

テスト3: シグナルをKILLする

  • mytraps:demoイメージを再実行 前に終了したコンテナを削除します。

最初のシェルで実行します。

docker container prune -f 

コンテナを再起動します。

docker container run -d --name mycontain mytraps:demo
  • docker のログでエコー出力を監視する

2つ目のシェル:

上矢印キーを押して前のコマンドを取得し、ENTERを押します。前と同じようにbashスクリプトの出力が表示されます。

  • docker kill経由で割り込みsignalを送る

最初のシェルで実行します。

docker container kill --signal SIGKILL  mycontain
  • ログで結果を見る

2つ目のシェル:

期待される出力 :

...
 . 6
 . 7
 . 8
 . 9
 . 10
 . 11
 . 12

SIGKILL シグナルをキャッチできません - スクリプトはクリーンアップルーチンを実行できません。

ログ出力も停止していることに注意してください: コンテナは、KILL シグナルによって即座にKILL された後、UNSUCCessfully に終了しました。

テスト 3 が完了しました: シグナル SIGKILL / 2 の処理が成功しました。

重要なまとめ: コンテナ内で実行しているプロセスは適切なクリーンアップルーチンを持っていなければなりません。Dockerでは、Docker以前の世界と比べて、コンテナのシャットダウンと再起動を頻繁に行うことになります。そのため、コンテナが様々なシャットダウン方法を正しく処理できるようにすることが重要です。

これらの演習に基づいて、たった2つのシグナルを扱うだけでどれだけ簡単にテストできるかがわかります。

シェルで trap -l と入力すると、64種類のシグナルのリストが表示されます。あなたのプロセスは、受信可能なすべての値を扱うことができなければなりません。

docker container kill の名前が間違っています。

docker container signal - とすべきだったのですが、設定ファイルを再読するためだけにシグナルを送ることができるからです。すべてのシグナルが kill するわけではありません。

SIGUSR1とSIGUSR2を任意の目的に使用できます。アプリケーションにこれらの信号を送信し、KILLだけでなく、何かを意味することができます。

Dockerコンテナの待ち時間

https://docs.docker.com/engine/reference/commandline/container_wait/ より

1つ以上のコンテナが停止するまでブロックし、その終了コードを印刷します。

これがどのように動作するかを調べるために、3つのコンテナを実行し、数秒スリープさせた後、固有の終了コードで終了させます。

以下を切り取ってシェルに貼り付けます。

docker container run -d --name mycontain1 mytraps:demo sh -c 'sleep 10;exit 1'
docker container run -d --name mycontain2 mytraps:demo sh -c 'sleep 15;exit 2'
docker container run -d --name mycontain3 mytraps:demo sh -c 'sleep 25;exit 3'

新しいシェルコンソールセッションを起動して実行します。

docker container wait mycontain1 mycontain2 mycontain3

コンテナのスリープ期間が終了すると、指定された終了コードで終了することに注意してください。

どのコンテナがどの終了コードで終了したかを示すものはありません。
どのコンテナがどの終了コードで終了したかを知る必要がある場合は、次のようにしてください。

docker ps -a

期待される出力 :

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
6c7fe618e23b        mytraps:demo        "sh -c 'sleep 25;exi…"   40 seconds ago      Exited (3) 14 seconds ago                       mycontain3
d4e1bb11e55c        mytraps:demo        "sh -c 'sleep 15;exi…"   43 seconds ago      Exited (2) 27 seconds ago                       mycontain2
bee5cbf37052        mytraps:demo        "sh -c 'sleep 10;exi…"   44 seconds ago      Exited (1) 33 seconds ago                       mycontain1

この機能はあまり有効ではありませんが、いくつかのバッチコンテナを1時間以上実行している場合などに利用できるかもしれません。すべてが正常に完了することを期待しています。

数分おきに docker ps -a を実行する代わりに (ワークフローを考えていた場合のように)、新しいシェルで以下のコマンドを使用してコンテナを監視することができます。すべてのコンテナが終了すると、コマンドは再びプロンプトを表示します。

(以下のコマンドは出力されませんので、自分で試してみてください。)

以下のコマンドは出力されません。

docker ps -a --filter "name=mycontain1"  --filter "name=mycontain2" --filter "name=mycontain3"

しかし、これは本当に長文になってしまいます。

すべてのコンテナは同じ画像を使うことに注意してください: mytraps:demo

docker ps -a --filter "ancestor=mytraps:demo"

ancestor filter: 与えられた画像を共有するコンテナをancestorとしてフィルタリングします。

以前よりもずっと短くなりました。

最短タイピングは

docker ps -a |grep mycontain

或いは

docker ps -a |grep mytraps

エイリアスmypsaを定義すると

alias mypsa='docker ps -a | grep ‘

を使用することができます。

mypsa traps
mypsa contain

docker container port

ポートマッピングまたはコンテナの特定のマッピングを一覧表示します。

docker ps -aもポートマッピングを表示しています。そのため、ここではこのコマンドを調査するつもりはありません。

チュートリアルクリーンアップ

プルーンで停止されたコンテナ:

docker container prune -f 

docker image rm mytraps:demo 

alpine:3.8の画像をよく使いました。今後も使うことがあると思いますので、削除しないことをお勧めします。

まとめ

この2つのチュートリアルでは、25個のdockerコンテナコマンドのほぼ全てを使用しました。あなたは今、あなたのコンテナに対して適用することができますどのようなコマンドを理解しています。

あなたが最短時間でDockerの専門家になりたい場合は、私はあなたがすべてのDockerの機能を使用して、同様の小さな、迅速な(しかし、非常に有用な)演習を行うことをお勧めします。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECRでKMSがサポートされるようになった

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VultrでKUSANAGI Runs on Dockerが動くまで(その2)

前回のおさらい

前回の記事『VultrでKUSANAGI Runs on Dockerが動くまで(その1)』ではVPC環境であるVultrにKUSANAGI RoDをインストールするところまで確認しました。
今回はWordpressを運用しやすくするため、Dockerコンテナの設定を少し変えていきたいと思います。

動作環境など

  • Ubuntu 20.04
  • docker 19.03.12
  • docker-compose 1.26.2
$ docker-compose ps
       Name                     Command               State         Ports       
--------------------------------------------------------------------------------
kusanagi01_certbot   certbot --version                Up                        
kusanagi01_config    docker-entrypoint.sh wp -- ...   Up                        
kusanagi01_db        docker-entrypoint.sh mysqld      Up                        
kusanagi01_ftp       /bin/sh -c /docker-entrypo ...   Up                        
kusanagi01_httpd     /docker-entrypoint.sh /usr ...   Up      8080/tcp, 8443/tcp
kusanagi01_php       /usr/local/bin/docker-entr ...   Up  

修正前のdocker-compose.yaml

プロビジョニング直後はこんな感じになっています。
【主な特徴】

  • それぞれのコンテナでDocumentRoot含む必要なファイル類を/home/kusanagiにマウント
  • kusanagiボリュームとdatabaseボリュームを永続化
docker-compose.yml
version: '3'

networks:
  default:
    driver: bridge
    driver_opts:
      com.docker.network.driver.mtu: 9000
  shared-network:
    external: true

services:
  httpd:
    container_name: kusanagi01_httpd
    image: primestrategy/kusanagi-nginx:1.17.9-r0
    restart: always
    env_file:
      - .kusanagi
      - .kusanagi.httpd
    volumes:
      - kusanagi:/home/kusanagi
      - kusanagi:/etc/letsencrypt
      - kusanagi:/var/www/html/.well-known
    ports:
      - "8080:8080"
      - "8443:8443"
    extra_hosts:
      - "domain.name:127.0.0.1"
    networks:
      - shared-network

  certbot:
    container_name: kusanagi01_certbot
    image: certbot/certbot:v1.6.0
    restart: always
    network_mode: "service:httpd"
    env_file:
      - .kusanagi.httpd
    volumes:
      - kusanagi:/var/www/html/.well-known
      - kusanagi:/etc/letsencrypt
    command:
      - --version

## CONFIG
  config:
    container_name: kusanagi01_config
    restart: always
    build:
        context: ./wpcli
    user: "1000:1001"
    env_file:
      - .kusanagi
      - .kusanagi.wp
      - .kusanagi.db
    volumes:
      - database:/var/run/mysqld
      - kusanagi:/home/kusanagi
    command: wp --version

  php:
    container_name: kusanagi01_php
    image: primestrategy/kusanagi-php:7.4.8-r0
    restart: always
    env_file:
      - .kusanagi
      - .kusanagi.php
      - .kusanagi.mail
    network_mode: "service:httpd"
    volumes:
      - database:/var/run/mysqld
      - kusanagi:/home/kusanagi

## MYSQL 
  db:
    container_name: kusanagi01_db
    image: mariadb:10.5.4-focal
    restart: always
    user: "999:999"
    env_file:
      - .kusanagi.mysql
    network_mode: "service:httpd"
    volumes:
      - database:/var/run/mysqld
      - database:/var/lib/mysql

## FTPD
  ftp:
    container_name: kusanagi01_ftp
    image: primestrategy/kusanagi-ftpd:1.0.2-r1
    restart: always
    network_mode: "service:httpd"
    env_file:
      - .kusanagi
      - .kusanagi.wp
    volumes:
      - kusanagi:/home/kusanagi


volumes:
  kusanagi:
  database:

今回の変更点

以下の点を変更します。

  1. nginxのログ出力をDockerの標準ログ出力に変更
  2. PHPのファイルアップロード設定を追加
  3. 不要なコンテナ(certbot)を停止

変更点1

nginxのログ出力をDockerの標準ログ出力に変更します。
nginxフォルダの中にnginx.confファイルを作成しhttpdコンテナのnginx.confを書き換えます。nginx.confの変更部分のみ記載しておきます。

$HOME/kusanagi01/nginx/nginx.conf
#error_log /var/log/nginx/error.log warn;
error_log /dev/stderr warn;

    #access_log /var/log/nginx/access.log  main;
    access_log /dev/stdout  main;

変更点2

デフォルトだと2MB以上のファイルアップロードができないのでPHPのファイルアップロード設定を追加します。
phpフォルダの中にuploads.iniファイルを作成しphpコンテナにuploads.iniを追加します。

$HOME/kusanagi01/php/uploads.ini
file_uploads = On
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 600

以下のようなフォルダ構成になります。

/home
  └$USER
        ├https-portal ← リバプロサーバー(マルチサイト& Let’s Encrypt対応)
        │ └docker-compose.yml
        │ 
        ├kusanagi01 ← KUSANAGI Runs on Docker(WordPressサイト1つ目)
        │ ├nginx                ※追加
        │ │ └nginx.conf         ※追加
        │ ├php                  ※追加
        │ │ └ uploads.ini       ※追加
        │ └docker-compose.yml
        │
        └kusanagi02 ← KUSANAGI Runs on Docker(WordPressサイト2つ目)
          └docker-compose.yml

変更点3

certbotコンテナが実験中で使われていないので起動しないようにします。
こちらはdocker-compose.ymlファイルで該当箇所をコメントアウトしてしまえばOKです。

修正後のdocker-compose.yml(抜粋)

docker-compose.yml
  #certbot:
    #container_name: kusanagi01_certbot
    #image: certbot/certbot:v1.6.0
    #restart: always
    #network_mode: "service:httpd"
    #env_file:
      #- .kusanagi.httpd
    #volumes:
      #- kusanagi:/var/www/html/.well-known
      #- kusanagi:/etc/letsencrypt
    #command:
      #- --version

コンテナの再作成

構成を変更したのでコンテナを作り直します。エラー無く起動することを確認します。

$ docker-compose down
$ docker-compose up -d

動作確認

変更が反映されているか確認していきます。

nginxのログ出力先変更

以下のコマンドでDockerのログを表示させWebのアクセスログが出力されることを確認します。

$ docker logs kusanagi01_httpd -f

PHPのファイルアップロード設定

phpinfoファイルを作成しコンテナにコピーし動作確認します。コンテナにシェルアクセスして作成してもよいですけどkusanagi-dockerコマンドでコンテナへのファイルコピーができます。

$HOME/content/DocumentRoot/test.php
<?php
    phpinfo()
?>
$ cd $HOME/kusanagi01
$ kusanagi-docker config push
chown: unknown user/group kusanagi:www
ERROR: Failed.

ブラウザでtest.phpにアクセスしてuploads.iniで変更した部分が反映されていることを確認しておきましょう。確認が終わったらtest.phpの削除も忘れずに。
VultrでKUSANAGI Runs on Dockerが動くまで(その3)に続きます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンテナに対して適用できるDockerコマンドを25個紹介:その1

このチュートリアルでは、コンテナに対して適用できる25のDockerコマンドを簡単にデモします。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

Bash エイリアス

dockerコンテナのコマンドは25個あり、それらの単語を繰り返し入力したくありません。そのため、エイリアスが必要です。

提案:

alias dock='docker container'

私にとってはdoccよりも入力しやすいです。

これは論理的に他のエイリアスとの整合性を取ることができます。

alias docv='docker volume'

alias doci='docker inspect'

alias docm='docker image'

alias psa='docker ps -a'

alias d='docker '

Docker Pull Alpine:3.8

すでにAlpine 3.8のDockerイメージを持っている場合は、ここで何もする必要はありません。

それ以外の場合は、シェルで以下のように入力してください。

docker pull alpine:3.8

Alpineのイメージをコンピュータにダウンロードします。

Dockerコンテナ:作成と実行

コンテナを作成して、25個のコマンドを適用できるようにしてみましょう。

実行中のコンテナを作成する方法はいくつかありますが、ここでは create and run を使います。

構文:

docker container run [options] IMAGE [command] [arg...]

docker container run -d --name mycontain alpine:3.8 sleep 3600

Dockerは、そのコンテナに対して生成した64文字のランダムなIDを表示します。

docker ps -a

これで実行中のコンテナができました。

Dockerコンテナの実行

コンテナの中に入って、その内部を探ることができます。

docker exec -it your-12-character-container-id  /bin/sh

it オプションは 2 つのオプションを指定します。

  • -i ... 対話的な docker exec にします。
  • -t ... で作業するための疑似ターミナル/シェルコンソールを与えてください。
  • /bin/sh は bash を実行するように指定します。

表示されている / # はコンテナシェルのプロンプトです。通常のシェルと同じように使います。

シェルを使用するには、以下のコマンドを入力します。

exit は特定のシェルセッションを終了します。コンテナはまだ実行中です。

/ # ps

PID  USER  TIME  COMMAND

1 root  0:00 sleep 3600

6 root  0:00 /bin/sh

11 root  0:00 ps

/ # ll

/bin/sh: ll: not found

/ # ls

bin  etc  lib  mnt  root  sbin  sys  usr

dev  home  media  proc  run  srv  tmp  var

/ # echo text > textfile

/ # cat  textfile

text

/ # df -h

Filesystem  Size  Used Available Use% Mounted on

tmpfs  64.0M  0  64.0M  0% /dev

tmpfs  492.6M  0  492.6M  0% /sys/fs/cgroup

/dev/mapper/centos00-root

12.6G  5.3G  7.3G  42% /etc/resolv.conf

/dev/mapper/centos00-root

12.6G  5.3G  7.3G  42% /etc/hostname

/dev/mapper/centos00-root

12.6G  5.3G  7.3G  42% /etc/hosts

shm  64.0M  0  64.0M  0% /dev/shm

tmpfs  492.6M  0  492.6M  0% /proc/acpi

tmpfs  64.0M  0  64.0M  0% /proc/kcore

tmpfs  64.0M  0  64.0M  0% /proc/keys

tmpfs  64.0M  0  64.0M  0% /proc/timer_list

tmpfs  64.0M  0  64.0M  0% /proc/timer_stats

tmpfs  64.0M  0  64.0M  0% /proc/sched_debug

tmpfs  492.6M  0  492.6M  0% /proc/scsi

tmpfs  492.6M  0  492.6M  0% /sys/firmware

/ # exit

Dockerコンテナの一時停止、一時停止解除

コンテナーを一時的に停止する必要がある場合は、それを行うことができます。
Dockerはコンテナ内のプロセスを一時停止するためにcgroupsのフリーザー機能を使用します。
コンテナ内のプロセスは認識しておらず、この一時停止をキャプチャ/防止することができません。
同様に、プロセスはunpauseを使用して再び起動します - プロセスは一時停止されたことを認識していません。

実行してください。

docker ps -a

コンテナが実行中/稼働中であることを確認します。

docker container pause your-12-character-container-id

docker ps -a

期待される出力 .

CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES

89187919f955  alpine:3.8  "sleep 3600"  49 seconds ago  Up 48 seconds (Paused)  mycontain

コンテナが(一時停止)であることに注意してください

残念ながら、一時停止中のコンテナに入って見て回ることはできません。このようなエラーが出ます。

デーモンからのエラー応答です。コンテナ 89187919f955 が一時停止しています。

ここで見るべきものは何もありません - 一時停止中のコンテナはCPUサイクルを使用していません。

一時停止を解除します。

docker container unpause your-12-character-container-id

実行

docker ps -a

ステータスが再び稼働していることを確認します。

CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES

89187919f955  alpine:3.8  "sleep 3600"  3 minutes ago  Up 3 minutes  mycontain

一時停止と一時停止解除コマンドにはオプションがありません。しかし、複数のコンテナを一度に一時停止したり、一時停止解除したりすることはできます。
例えば、

docker container pause cont1 apache2 php42 othercont and-so-on

Dockerコンテナの起動、停止、再起動、イベント

これらのコマンドが何をするかを表示するには、次のように入力します。

別のシェルセッションでdockerのイベントを表示するようになりました。これでDockerのイベントが発生したときに表示されるようになりました。

元の最初のシェルに戻ります。

docker container stop 89187919f955

停止するまでに10秒かかるので注意してください。

docker ps -aを実行すると、そのステータスが表示されます。

イベントシェルに戻ります。出力を観察してください。

期待される出力

2018-11-15T10:24:09.584676893+02:00 container kill 89187919f9554894a7304f772631d48a894c609daf333eadbd53f55f8555b0a1 (image=alpine:3.8, name=mycontain, signal=15)

2018-11-15T10:24:19.605895426+02:00 container kill 89187919f9554894a7304f772631d48a894c609daf333eadbd53f55f8555b0a1 (image=alpine:3.8, name=mycontain, signal=9)

2018-11-15T10:24:19.758338864+02:00 container die 89187919f9554894a7304f772631d48a894c609daf333eadbd53f55f8555b0a1 (exitCode=137, image=alpine:3.8, name=mycontain)

2018-11-15T10:24:19.854403805+02:00 network disconnect 4cdddf0dfbaa8d697920bc6e387c9306941d680b054e9026fc52d3dd763cd05a (container=89187919f9554894a7304f772631d48a894c609daf333eadbd53f55f8555b0a1, name=bridge, type=bridge)

2018-11-15T10:24:19.904432478+02:00 container stop 89187919f9554894a7304f772631d48a894c609daf333eadbd53f55f8555b0a1 (image=alpine:3.8, name=mycontain)

signal 15 終了が送信され、これにより、コンテナにクリーンシャットダウンルーチンを実行する機会が与えられます。

10秒後、まだシャットダウン中であれば、即座に強制的に強制終了signal9で強制終了されます。150 ミリ秒後に終了します。

CTRL-cを押して、このイベント表示を中断します。以上で終了です。

元のシェルに戻ります。

docker container restart your-12-character-container-id

docker ps -aを実行すると、そのステータスが表示されます。

Dockerコンテナの停止 --time 0

開発に忙しい中、この10秒を待つ忍耐力がありません。(おそらく私のシャットダウンクリーンアップルーチンがまだ書かれていないのでしょう。)

そのため、数日間はコンテナをすぐに停止させます。

コンテナはまだ動いています。

イベントシェルに切り替えます。

docker のイベントを再度実行して、異なるイベントを観測できるようにします。

元のシェルに戻ります。

docker container stop --time 0 your-12-character-container-id

すぐに停止することに注意してください。

イベントシェルに切り替えます。

期待される出力 .

2018-11-15T10:39:40.364765468+02:00 container kill 89187919f9554894a7304f772631d48a894c609daf333eadbd53f55f8555b0a1 (image=alpine:3.8, name=mycontain, signal=15)

2018-11-15T10:39:40.380549365+02:00 container kill 89187919f9554894a7304f772631d48a894c609daf333eadbd53f55f8555b0a1 (image=alpine:3.8, name=mycontain, signal=9)

2018-11-15T10:39:40.524409344+02:00 container die 89187919f9554894a7304f772631d48a894c609daf333eadbd53f55f8555b0a1 (exitCode=137, image=alpine:3.8, name=mycontain)

2018-11-15T10:39:40.613037711+02:00 network disconnect 4cdddf0dfbaa8d697920bc6e387c9306941d680b054e9026fc52d3dd763cd05a (container=89187919f9554894a7304f772631d48a894c609daf333eadbd53f55f8555b0a1, name=bridge, type=bridge)

2018-11-15T10:39:40.661786770+02:00 container stop 89187919f9554894a7304f772631d48a894c609daf333eadbd53f55f8555b0a1 (image=alpine:3.8, name=mycontain)

terminate 15信号の15秒後にforcefull kill 9信号が送信されていることに注意してください。

本番環境では絶対にこの --time 0 を使用しないでください。これはデータの破損を保証します。

しかし、開発では学習やプログラミングのサイクルを早めることができます。

DockerコンテナのKill

実行中の Linux プロセスに送ることができる可能性のあるシグナルの長いリストがあります。

https://en.wikipedia.org/wiki/Signal_(IPC)

これでイベントシェルコンソールの使い方がわかりました。

これを使って以下のテストを行います。

docker container kill --signal 15 your-12-character-container-id

様子を見ます。

docker container kill --signal 15 your-12-character-container-id

様子を見ます。

docker container kill --signal 15 your-12-character-container-id

様子を見ます。

docker container kill --signal 9 your-12-character-container-id

様子を見ます。

signal15はそのsignalだけを送信することに注意してください。私たちの単純なコンテナは、きれいにシャットダウンする方法を知らないので、それを無視するだけです。

signal9はコンテナを即座にkillします。

Linux で利用可能なシグナルの完全なセットを送信するために docker container kill を使うことができます。

ポータブル番号(wikiページの表にある)か大文字のシグナル名を使うことができます。

残念ながら、私たちの単純な sleep 3600 コマンドはシグナルをキャッチして処理する方法を知らないので、無視します。

本当に必要なのは、これらのシグナルをキャッチするために特別に書かれたbashスクリプト、phpまたはpythonプログラムで、これがどのように動作するかを見ることです。

このチュートリアルでは、DockerコンテナがLinuxのシグナルをフルセットで受信できることを知っていただきたいと思います。

Dockerコンテナのリネーム

構文は以下の通りです。

docker コンテナの rename OLD-CONTAINER-NAME NEW-OLD-CONTAINER-NAME

おそらく停止しているコンテナは1つだけになったでしょう。だから再起動してください。

docker container restart your-12-character-container-id

docker ps -a

期待される出力 .

CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES

89187919f955  alpine:3.8  "sleep 3600"  About an hour ago  Up 1 second  mycontain

コンテナの名前を変更してみましょう。

docker container rename mycontain new-contain-name

結果を観察します。

docker ps -a

期待される出力 .

CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES

89187919f955  alpine:3.8  "sleep 3600"  About an hour ago  Up About a minute  new-contain-name

Dockerのソースコードから直接。

// コンテナ名を表すために許可されている文字数

const RestrictedNameChars = [a-zA-Z0-9][a-zA-Z0-9_.-]

コンテナ名は最初のブロックの文字から始まることに注意してください : [a-zA-Z0-9]

Dockerコンテナのアップデート

このコマンドを使用して、1つまたは複数のコンテナのランタイムのCPUまたはRAMの制限を更新します。

設定するオプションの完全なリスト:

https://docs.docker.com/engine/reference/commandline/container_update/#options

コンテナを再起動します。

docker container restart your-12-character-container-id

CpusetCpusの設定だけを表示します。

docker container inspect your-12-character-container-id  | grep "CpusetCpus"

このコンテナでは、CPU 番号 0 のみを使用できるようにしてみましょう。

docker container update --cpuset-cpus 0  your-12-character-container-id

その設定がうまくいったかどうかを確認してください。

docker container inspect your-12-character-container-id  | grep "CpusetCpus"

期待される出力 .

"CpusetCpus". "0",

成功しました。コンテナはCPU 0のみに制限されています。

docker container updateを使って、実行中のコンテナのそのウェブページ上のすべての設定を更新することができます。

Docker Container ls

サーバー上のコンテナのリストを表示します。

実行してください。

docker container ls -a

その出力は次のものと同じです。

docker ps -a

a は、実行中と終了したすべてのコンテナを表示します。

この2つのコマンドは同じオプションを持っています。私はbash psaエイリアスを定義しているので、docker ps -aのみを使用しています。

Docker Container cp

コンテナとローカルファイルシステムの間でファイル/フォルダをコピーする

コンテナにコピーする構文 .

docker cp [OPTIONS] HOST_SRC_PATH|- CONTAINER:DEST_PATH

ホストサーバー上にファイルを作成し、コンテナにコピーします。

echo text-to-copy > file-to-copy

ファイルをコンテナにコピーします。

docker container cp file-to-copy your-12-character-container-id:/

ディレクトリの内容を一覧表示します。

docker exec -it  your-12-character-container-id  ls /

ファイルがあることがわかります。

Docker Container Stats と Top

コンテナのランタイム統計を表示します。以下を参照してください。

docker container stats --no-stream
CONTAINER ID  NAME  CPU %  MEM USAGE / LIMIT  MEM %  NET I/O  BLOCK I/O  PIDS

89187919f955  new-contain-name  0.00%  44KiB / 985.2MiB  0.00%  648B / 0B  1.41MB / 0B  0

この出力を以下と比較します。

docker container top your-12-character-container-id

期待される出力 .

UID  PID  PPID  C  STIME  TTY  TIME  CMD

root  4058  4040  0  12:31  ?  00:00:00  sleep 3600

私は docker container statsの方がずっと便利だと思います。

しかし、top の PID を使って通常の top コマンドを実行すれば、Linux ディストロ上で実行されているプロセスの通常の詳細を見つけることができます。

これらの PID のみを表示するように編集された出力。

Tasks: 114 total,  1 running, 113 sleeping,  0 stopped,  0 zombie

%Cpu(s):  0.2 us,  0.2 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

MiB Mem :  985.219 total,  545.160 free,  126.871 used,  313.188 buff/cache

MiB Swap: 1499.996 total, 1499.996 free,  0.000 used.  688.348 avail Mem

PID USER  PR  NI  VIRT  RES  SHR S  %CPU %MEM  TIME+ COMMAND

4040 root  20  0  7.3m  3.3m  2.6m S  0.3  0:00.08 docker-containe

4058 root  20  0  1.5m  0.2m  0.2m S  0.0  0:00.04 sleep

Dockerコンテナの差分

コンテナのファイルシステム上のファイルやディレクトリの変更を表示します。

そのファイルを数分前にコンテナにコピーしました。

diff はコンテナのファイルシステムへの変更を表示します。

docker container diff your-12-character-container-id

期待される出力 .

A /text-to-copy

動作します - 追加されたファイルが表示されます。

コンテナのファイルシステムに何度か変更を加えた場合は、より興味深い出力が表示されます。

Dockerコンテナのログとアタッチ

  • docker コンテナのログ ... コンテナのログを表示
  • docker コンテナ アタッチ ... 標準入力STDIN、出力、エラーストリームにアタッチ

ここで、ログと、表示コンテナログを添付するさまざまな方法を学びます。

私たちは、検査するためのログラインを生成する別のコマンドを持つ新しいコンテナが必要です。

最初に私たちの最後のコンテナのステータスを決定するためにdockerのps -a -を行います。

status = exitedであれば、それで問題ありません。

そうでなければ実行してください。

docker container stop your-12-character-container-id

今、そのコンテナをプルーニング/削除します。

docker container prune -f

ここに新しいコンテナを実行するコマンドがあります - まだ実行しないでください。

docker container run -d --name mycontain alpine:3.8 /bin/sh -c 'for i in 1 2 3 4 5 6 7 8 9 10 ; do echo $i; sleep 5; done'

10 回ループし、その都度ループ回数をエコーし、5 秒間スリープさせた後に継続します。

これらのエコー出力はコンテナのログに書き込まれます。

エコー文とエコー文の間に 5 秒間スリープします。

2 番目のシェルセッションを開始します - 先ほどのイベントシェルを再利用することができます。

これら2つのコマンドを入力してください - エラーメッセージが表示されます - これでOKです。これらのコマンドを bash のコマンド履歴に残しておくと、キーボードの上矢印キーを使ってすぐに呼び出すことができます。

docker container logs --follow mycontain

docker container attach mycontain

元のシェルに戻ります。

実行

docker container run -d --name mycontain alpine:3.8 /bin/sh -c 'for i in 1 2 3 4 5 6 7 8 9 10 ; do echo $i; sleep 5; done'

あなたのコンテナは実行中で、5秒ごとに増加するカウンタをエコーして、コンテナログに書き込んでいます。

ここで、2 番目のシェルに切り替えます。

キーボードの上矢印を2回押してログを取得します。表示されたらエンターキーを押してください。

logs コマンドには echo された数値が表示されます。飽きたらCTRL-cを押してください。

キーボードの上矢印を2回押して、attachコマンドを取得します。それが表示されたらエンターキーを押します。

attach コマンドは echo'ed 番号を表示します。飽きたら CTRL-c を押してください。

問題点。添付ファイルの出力を表示しているときに CTRL-c キーを押すと、bash のループ処理から抜け出すことができます: コンテナが終了します。

ログ出力を表示中に CTRL-c を実行しても、bash for loop から抜け出せません。

したがって、私は常にlogsコマンドを使用することを好みます。

ウェブサーバプロセスを実行している場合は、それをアタッチして CTRL-c を押すと、CTRL-c をウェブサーバプロセスに送信して停止させることができます。

もし、添付ファイルを作成する前にエコー番号が切れてしまった場合は、 再度実行することができます。最初からやり直してください...

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dockerでOpenLDAPを使う

LDAP

  • Lightweight Directory Service

環境

  • Ubuntu20.04(wsl2)

手順

docker-comppose.yml

docker-compose.yml
version: '3'

services:
  ldap-server:
    image: osixia/openldap:latest
    restart: always
    container_name: ldap-host
    environment:
      LDAP_ORGANISATION: "vamp"
      LDAP_DOMAIN: "vamdemic.black"
      LDAP_ADMIN_PASSWORD: "password"
    ports:
      - "389:389"
    networks:
      - webnet

  ldap-admin:
    image: osixia/phpldapadmin:latest
    restart: always
    container_name: ldap-admin
    environment:
      PHPLDAPADMIN_LDAP_HOSTS: "ldap"
      PHPLDAPADMIN_HTTPS: "false"
    ports:
      - "8080:80"
    links:
      - "ldap-server:ldap"
    networks:
      - webnet

networks:
  webnet:

起動

sudo docker-compose up -d

起動確認

yuta@DESKTOP-PT34LID:/mnt/c/Users/yuta/openldap$ sudo docker-compose ps
   Name            Command         State               Ports
------------------------------------------------------------------------
ldap-admin   /container/tool/run   Up      443/tcp, 0.0.0.0:8080->80/tcp
ldap-host    /container/tool/run   Up      389/tcp, 636/tcp

PHPAdminへログイン

image.png

  • ユーザー名はadmin
  • cn=admin,dc=vamdemic,dc=black image.png

image.png

ユーザーを作る

まずOUを作る

image.png

ユーザーを作る

  • ouを選んでcreate new child entry
  • kolab user entryを選ぶ
    image.png

  • Requireの箇所を埋めれば作れる

image.png

結果

image.png

image.png

ldapsarchで検索をかける

ldapsearch -x -D "CN=admin,DC=vamdemic,DC=black" -w 'password' -h "localhost" -p 389 -b "OU=vamp,DC=vamdemic,DC=black" "cn=yuta"

インストールされていない場合

sudo apt install ldap-utils

出力

# extended LDIF
#
# LDAPv3
# base <OU=vamp,DC=vamdemic,DC=black> with scope subtree
# filter: cn=yuta
# requesting: ALL
#

# yuta, vamp, vamdemic.black
dn: cn=yuta,ou=vamp,dc=vamdemic,dc=black
sn: yuta
cn:: IHl1dGE=
objectClass: inetOrgPerson
objectClass: top

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

参考

https://qiita.com/yoshiyasu1111/items/c2d7d5f9a70afdaa8372

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dockerを動かすときにはまる所の解決Tips

Dockerのエラーを解決しましょう!

Dockerではまったところのメモを残しておきます。
参考になれば幸いです。

Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running?

sudo: docker-compose: コマンドが見つかりません

上記でsudoした結果。
原因:)
visudo で編集できる secure_path に/usr/local/bin が含まれていない。
docker-composeは /usr/local/bin 配下にインストールされる。

解決:)

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/local/bin:/usr/bin

ENOSPC no space left on device

ホストの容量が不足している時にでてきます。
対処法はいくつかあって、
1、dfやduで不要なボリュームをつき止めて削除する
2、dockerを入れ直す
3、docker system pruneなどで綺麗にしてもう一度試す。
あたりがメジャーです。

ここではdocker-cleanをご紹介します。
自分はこれで直ったことが多いです。

以下のコマンドで導入可能です。

//brew
brew install docker-clean

or
// brew以外
curl -s https://raw.githubusercontent.com/ZZROTDesign/docker-clean/v2.0.4/docker-clean |
sudo tee /usr/local/bin/docker-clean > /dev/null && \
sudo chmod +x /usr/local/bin/docker-clean

導入したらコマンドは

docker-clean all

これで不要なものが削除されます。

詳細はこちら↓
https://github.com/ZZROTDesign/docker-clean

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerよく使うコマンド集

はじめに

投稿者の勉強用&Dockerコマンドを覚えたい人向けです。

立ち上がっているコンテナを確認

docker ps

コンテナのサイズ確認

docker ps -s

既に終了しているコンテナを含め確認

docker ps -a

Dockerイメージを作成

docker build -t (コンテナ名):(バージョン) (Dockerfileの場所)

docker-composeで管理するコンテナをビルドする

docker-compose build

docker-composeで管理するコンテナをバックグラウンドで実行

docker-compose up -d

docker-composeで管理しているコンテナを終了しコンテナを削除する

docker-compose down

docker-composeで管理しているコンテナを終了する

docker-compose stop

dockerコンテナ内にアクセス

docker exec -it (コンテナID/コンテナ名) (bash/sh)

toolboxの場合

winpty docker exec -it (コンテナID/コンテナ名) (bash/sh)

コンテナIDを指定する場合は最初の1文字だけでOK(被ってない時に限る)
例えばe626a2e78420の場合は
docker exec -it e bash

削除系

使っていないNetWorkを削除

docker network prune

使っていないVolumeを削除

docker volume prune

使っていないContainerを削除

docker container prune

使っていない系一括削除

docker system prune

既に終了しているコンテナを削除する

docker rm (コンテナID/コンテナ名)

起動しているコンテナを含め強制的にすべて削除する

docker rm -f `docker ps -aq`
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python"再"入門1 実行環境の構築

はじめに

Python再入門ということで、Pythonの基本文法などの復習用に記事を書いていきます。

私がプログラミングを始めたちょうど1年前、当時の私はPythonを使って何か作ってみようと手を動かしていました。
それから一年が経った今は主にRubyを使ってWebアプリの開発を行っています。

ここにきてもう一度Pythonを復習しようと思ったきっかけは、就職先が決まったことにあります。
私は来年の4月に就職予定なのですが、就職予定の企業では機械学習や深層学習を使ったサービスを開発しています。
私は機械学習エンジニアとして就職するわけではありませんが、「触ったことある」ぐらいにはなっていた方がサービスの理解もしやすいのかなと考えています。
Pythonは機械学習系のライブラリも充実しているという印象があるので、まずはPythonを学ぶことから始めることにしました。

冒頭でお伝えした通り、私がプログラミングに入門した際に初めて触った言語はPythonなのですが、忘れっぽい私は文法などを完全に忘れてしまったので、今回記事を残しながら再入門をしていこうと思います。

対象読者

  • プログラミングの経験があり、Pythonを初めてみたい人
  • 機械学習などに興味があり、Pythonから勉強してみようと考えている人

注意

私は、Pythonを使って機械学習や深層学習の実装をしてみたいという理由でまずはPythonの文法を復習するところからスタートしています。
注意点として、"Pythonでコードがかける" = "機械学習ができる"ではありません。
機械学習や深層学習に興味はあるけど、概念がわかれば実装まではしなくていいや、という方はそういった目的の記事や書籍を参考にされたら良いかと思います。

↓ここからが本題

Python実行環境の構築

Jupyter Notebookの導入

Jupyter Notebookを使うと、Webブラウザを使ってPythonのコードを入力して実行することができます。
インタラクティブシェルのような感じで書いたコードを実行することができ、手を動かしてPythonについて学ぶにはとても便利です。

Jupyter Notebookを使えるようにするにはAnaconda Navigatorをインストールするのが早いです。

※Anaconda Navigatorとは?

Anaconda Navigatorとは、Pythonの開発に必要な多くのソフトがまとめられているディストリビューション。
Jupyter Notebookやspyderといった便利ツールが最初から入っています。

Anaconda Navigatorインストール手順

mac用インストール手順(公式)
win用インストール手順(公式)

上記の手順にしたがってインストールしたAnaconda Navigatorを起動すれば、メニューの中にJupyter Notebookが表示されているはずです。

Jupyter Notebookの基本的な使い方については他の記事に投げることにします。

データ分析で欠かせない!Jupyter Notebookの使い方【初心者向け】

Dockerコンテナ内にJupyter Notebookを導入

ここからはPCの環境を汚したくない方向けの内容です。
特に気にならない方は上記の方法でJupyter Notebookをインストールすれば問題ありません。

dockerを使ったjupyter notebookの環境構築ですが、こちらはmacユーザー向けの手順になりますのでご容赦ください。

1. Dockerイメージをとってくる

Docker Hubにimageが公開されているのでこちらを使用します。
jupyter/scipy-notebook
jupyter/docker-stacks

今回は作業用のディレクトリとして、ipython_notebookを作成して作用していきます。

ちなみにIPython NotebookはJupyter Notebookの古い名前です。
元々はPython向けのツールでしたが、現在はRubyなど他のスクリプト言語を実行できるようにもなり改名したそうです。

イメージをとってくる。

ipython_notebook
$docker pull jupyter/scipy-notebook
$docker image ls #jupyter/scipy-notebookが表示されることを確認

最後のコマンドを実行してjupyter/scipy-notebookが表示されていればOKです。

2.ホストのディレクトリをマウント(する準備)

作業をしていくに当たって、ホストのディレクトリをマウントしておきたいので、/ipython_notebook以下にcodeディレクトリを作成します。

まず、Dockerが/UsersがDocker for Macとの共有ディレクトリになっていることを確認します。(今回はipython_notebookディレクトリがUsers以下に存在しているため)
確認方法についてはこちらの記事がわかりやすかったため参照されてください。

ipython_notebook
$mkdir code
$cd code
$pwd #こちらのコマンドの結果を後ほど使用します。

3. コンテナの作成

次に1でとってきたイメージからコンテナを作成します。
また、コンテナ作成時に、2で作成したcodeディレクトリをvolumeとしてマウントします。

以下のコードを実行すれば、2で作成したディレクトリをマウントしたコンテナが作成されます。
ここで注意が必要なのは/Users/.../ipython_notebook/code...部分は人によって異なる点です。
ボリュームの指定は-v ホストディレクトリのパス:コンテナ内のディレクトリパスとなるので、ここでのホストディレクトリのパスには先ほどpwdコマンドを実行した結果をペーストしてください。

ipython_notebook
$docker run -p 8888:8888 --name jupyter -v \
/Users/.../ipython_notebook/code:/home/jovyan/work \
jupyter/scipy-notebook

上記のコマンドを実行すると次のような実行結果が出ると思うので、token=以下の文字列をコピーしておきます。
スクリーンショット_2020-07-30_0_45_05.png

-p 8888:8888のオプションをつけたため、任意のブラウザからhttp://localhost:8888にアクセスすると認証のページが開きます。
ここで↑でコピーした認証用のトークンを入力して、新規でパスワードを入力しログインしてください。(設定したパスワードは次回以降のログインで必要になります。)

2回目移行の立ち上げ

上記で実行したコンテナを停止する際にはCtrl Cコンテナが停止します。
2回目以降にコンテナを起動する際にはdocker start jupyterを実行すれば立ち上がります。
コンテナを停止する際にはdocker stop jupyterを実行すれば停止します。

ipython_notebook
#上記で実行したコンテナを停止する場合
Ctrl + C
#2回目以降コンテナを立ち上げる場合
$docker container start jupyter
#docker container startで起動したコンテナを停止する場合
$docker container stop jupyter

以上でDockerを使用した場合のJupyter Notebookの環境構築は終了になります。

次回からはPythonの基礎文法について書いていきます。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む