かべぎわブログ

ブログです

docker buildでDockerfileからイメージを作成してみる

概要

docker buildコマンドを利用してDockerファイルからイメージを作成してみたいと思います。
今回はベースイメージを指定しただけの超シンプルなやつでやってみます。

Dockerファイル

DockerファイルにはもととなるイメージをFROMで記載と、MAINTAINERでこのファイルの作成者を残しています。
それだけです。

FROM centos
MAINTAINER kabegiwa

コマンド

docker build -t 作成するイメージ名 Dockerfileの格納ディレクトリ で実行してあげます。

$ sudo docker build -t wawawa ./docker_file_dir

Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos
 ---> 49f7960eb7e4
Step 2/2 : MAINTAINER kabegiwa
 ---> Running in ca0841dc9a55
Removing intermediate container ca0841dc9a55
 ---> 6e30b72c6abc
Successfully built 6e30b72c6abc
Successfully tagged wawawa:latest

確認

Dockerイメージが無事にできあがっていた。

$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
wawawa              latest              6e30b72c6abc        About a minute ago   200MB

おわりに

Dockerfileからイメージを作成することができた。

Docker

Docker

Dockerコンテナを一発ですべて停止する

概要

Dockerコンテナがたまりにたまっていたのでそれらを一括停止してみる。

コマンド例

以下コマンドを実行することでコンテナをすべて停止することができます。

$ sudo docker stop $(sudo docker ps -aq)

ちょっとした説明

docker ps -aqコマンドで停止しているコンテナも含めてすべてのコンテナIDを表示してくれます。
それを$()でコマンド展開してわたしてあげることですべてのコンテナIDにdocker stopを実行しています。

おわりに

テロも可能

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

シェルスクリプトで大文字小文字を置換する

概要

シェルスクリプト上で大文字と小文字置換してみたいと思います。

コマンド例

だいたいこんなかんじ。

大文字から小文字へ置換

$ echo "WAWAWA" | tr '[:upper:]' '[:lower:]'
wawawa

これでもできる。

$ echo "WAWAWA" | tr '[A-Z]' '[a-z]'
wawawa

小文字から大文字へ置換

$ echo "WAWAWA" | tr '[:upper:]' '[:lower:]'
wawawa

これでもできる。

$ echo "WAWAWA" | tr '[a-z]' '[A-Z]'
wawawa

おわりに

tr 置換前 置換後

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

  • 作者: ブルース・ブリン,Bruce Blinn,山下哲典
  • 出版社/メーカー: ソフトバンククリエイティブ
  • 発売日: 2003/02
  • メディア: 単行本
  • 購入: 18人 クリック: 331回
  • この商品を含むブログ (64件) を見る

Dockerコンテナをexportして別のサーバでimportして動作させる

Dockerコンテナを一旦exportして別のサーバ上でimportして動作させて見たいと思います。
環境が変わってもDockerイメージさえあれば同じ環境がすぐにできあがるよ。
みたいなことを確認してみたいと思います。

docker commit でイメージを作成する

docker commit -a 作成者 コンテナ識別子 イメージ名で指定してあげます。

$ sudo docker commit -a "kabegiwa" 5bc287372e97 wawawa_version

確認する

$ sudo docker inspect wawawa_version | grep -e "Author\|wawawa"
            "wawawa_version:latest"
        "Author": "kabegiwa",

docker export でコンテナをtarファイルにする

docker export コンテナ識別子をリダイレクトしてあげます。

$ sudo docker export 5bc287372e97 > wawawa_docker.tar

確認する

$ ls -l wawawa_docker.tar 
-rw-rw-r-- 1 ec2-user ec2-user 208245248  7月 30 19:57 wawawa_docker.tar

docker import でtarファイルからDockerイメージを作成する

事前準備として今回は別の環境でも動くことを確認したいのでscpでtarファイルをとってくる。

$ scp ec2-user@192.140.1.1:/home/ec2-user/wawawa_docker.tar ./.

docker import tarファイル イメージ名でDockerイメージをimportする

$ sudo docker import wawawa_docker.tar wawawa_version
sha256:d05784c4f35f845aa905357400391e608d7168116ef1b00c5aee3d487dbea922

確認する
まず、イメージの作成は完了した

$ sudo docker images 
REPOSITORY             TAG                 IMAGE ID            CREATED              SIZE
wawawa_version         latest              d05784c4f35f        2 seconds ago        200MB

docker runでもちゃんとうごく。

$ sudo docker run  d05784c4f35f /bin/bash
$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
ea6ff4ffa5dc        d05784c4f35f        "/bin/bash"         9 seconds ago       Exited (0) 8 seconds ago                       sad_bose

おわり。
別環境でも同じコンテナが同じように動いた。

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

ソートできないファイル同士を結合するシェルスクリプト

概要

なぜかはわからないけれどソートができないテキストファイル2つがあって、なぜかはわからないけれどそれを共通のキーをもとに結合したいときがあって、前述の通りなぜかはわからないけれどソートができないのでjoinコマンドが使えないのでシェルスクリプトをつくった。

スクリプト

つかってみる

たとえばこんなテキストファイルがあったとする。

$ cat aaa.txt 
AAA
CCC
BBB
$ cat bbb.txt 
CCC
AAA
DDD
BBB

それをこのスクリプトを実行するとこう

$ ./not_sort_join.sh -1 1 -2 1 aaa.txt bbb.txt
AAA AAA
CCC CCC
BBB BBB

一致しないカラムのやつはでない。

おわりに

一致しないカラムのやつを出すのも簡単に作れると思うけどいまのところぼくが必要ない。

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

  • 作者: ブルース・ブリン,Bruce Blinn,山下哲典
  • 出版社/メーカー: ソフトバンククリエイティブ
  • 発売日: 2003/02
  • メディア: 単行本
  • 購入: 18人 クリック: 331回
  • この商品を含むブログ (64件) を見る

AnsibleのshellモジュールでPATHがとおってないと怒られるときの対処法

概要

Ansibleのshellモジュールでターゲットノードでコマンドを実行しようとしたところ、「コマンドが見つかりません」というエラーが返ってきてしまいました。
のでそれの対処法です。

こんなかんじのplaybookがエラーになった。

- hosts: target
  tasks:
    - shell: ifconfig
$ ansible-playbook -i ./inventory_file ./shell_path.yml -v

PLAY [target] ******************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************
ok: [192.140.1.62]

TASK [command] *****************************************************************************************************************************************
fatal: [192.140.1.62]: FAILED! => {"changed": true, "cmd": "ifconfig", "delta": "0:00:00.003005", "end": "2018-07-24 13:58:14.304449", "msg": "non-zero return code", "rc": 127, "start": "2018-07-24 13:58:14.301444", "stderr": "/bin/sh: ifconfig: コマンドが見つかりません", "stderr_lines": ["/bin/sh: ifconfig: コマンドが見つかりません"], "stdout": "", "stdout_lines": []}
    to retry, use: --limit @/home/ec2-user/shell_path.retry

PLAY RECAP *********************************************************************************************************************************************
192.140.1.62               : ok=1    changed=0    unreachable=0    failed=1   

原因究明

ifconfigコマンドを実行したところ「コマンドが見つかりません」というエラーになった。
PATHがとおっていなさそうなので調べてみる。
こんなかんじのplaybookを用意。

- hosts: target
  tasks:
    - shell: echo ${PATH}

実行してみる。

$ ansible-playbook -i ./inventory_file ./shell_path.yml -v

PLAY [target] ******************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************
ok: [192.140.1.62]

TASK [command] *****************************************************************************************************************************************
changed: [192.140.1.62] => {"changed": true, "cmd": "echo ${PATH}", "delta": "0:00:00.002629", "end": "2018-07-24 13:59:18.802630", "rc": 0, "start": "2018-07-24 13:59:18.800001", "stderr": "", "stderr_lines": [], "stdout": "/usr/local/bin:/usr/bin", "stdout_lines": ["/usr/local/bin:/usr/bin"]}

PLAY RECAP *********************************************************************************************************************************************
192.140.1.62               : ok=2    changed=1    unreachable=0    failed=0   

PATHには/usr/local/bin:/usr/binしか設定されていないことがわかる。
ifconfigコマンドは/usr/sbin/ifconfigに格納されているのでエラーとなっていた。

$ which ifconfig
/usr/sbin/ifconfig

解決方法

shellモジュールに記載するコマンドを絶対PATHで書いてあげる。

- hosts: target
  tasks:
    - shell: /usr/sbin/ifconfig
$ ansible-playbook -i ./inventory_file ./shell_path.yml -v 

PLAY [target] ******************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************
ok: [192.140.1.62]

TASK [command] *****************************************************************************************************************************************
changed: [192.140.1.62] => {"changed": true, "cmd": "/usr/sbin/ifconfig", "delta": "0:00:00.003328", "end": "2018-07-24 14:02:56.630454", "rc": 0, "start": "2018-07-24 14:02:56.627126", "stderr": "", "stderr_lines": [], "stdout": "eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001\n        inet 192.140.1.62  netmask 255.255.255.0  broadcast 192.140.1.255\n        inet6 fe80::49c:a8ff:fe3f:24ae  prefixlen 64  scopeid 0x20<link>\n        ether 06:9c:a8:3f:24:ae  txqueuelen 1000  (Ethernet)\n        RX packets 10822  bytes 5943861 (5.6 MiB)\n        RX errors 0  dropped 0  overruns 0  frame 0\n        TX packets 7016  bytes 1080402 (1.0 MiB)\n        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0\n\nlo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536\n        inet 127.0.0.1  netmask 255.0.0.0\n        inet6 ::1  prefixlen 128  scopeid 0x10<host>\n        loop  txqueuelen 1  (Local Loopback)\n        RX packets 1576  bytes 1885056 (1.7 MiB)\n        RX errors 0  dropped 0  overruns 0  frame 0\n        TX packets 1576  bytes 1885056 (1.7 MiB)\n        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0", "stdout_lines": ["eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001", "        inet 192.140.1.62  netmask 255.255.255.0  broadcast 192.140.1.255", "        inet6 fe80::49c:a8ff:fe3f:24ae  prefixlen 64  scopeid 0x20<link>", "        ether 06:9c:a8:3f:24:ae  txqueuelen 1000  (Ethernet)", "        RX packets 10822  bytes 5943861 (5.6 MiB)", "        RX errors 0  dropped 0  overruns 0  frame 0", "        TX packets 7016  bytes 1080402 (1.0 MiB)", "        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0", "", "lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536", "        inet 127.0.0.1  netmask 255.0.0.0", "        inet6 ::1  prefixlen 128  scopeid 0x10<host>", "        loop  txqueuelen 1  (Local Loopback)", "        RX packets 1576  bytes 1885056 (1.7 MiB)", "        RX errors 0  dropped 0  overruns 0  frame 0", "        TX packets 1576  bytes 1885056 (1.7 MiB)", "        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0"]}

PLAY RECAP *********************************************************************************************************************************************
192.140.1.62               : ok=2    changed=1    unreachable=0    failed=0   

実行できた。

おわりに

もっとスマートな解決方法はないものか…

Ansible実践ガイド 第2版 (impress top gear)

Ansible実践ガイド 第2版 (impress top gear)

docker diffでコンテナ内の変更を確認する

概要

docker diffコマンドをつかってコンテナ起動からのコンテナ内の変更を確認してみます。

コマンド例

たとえばこんなかんじでコンテナ内にいろいろファイルをつくってみるとする。

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
5bc287372e97        centos              "/bin/bash"         16 minutes ago      Up 16 minutes                           elegant_ride

$ sudo docker exec -it 5bc287372e97 /bin/bash
# touch wawawa
# echo sasasa > sasasa.txt
# ls -l wawawa sasasa.txt 
-rw-r--r-- 1 root root 7 Jul 18 13:49 sasasa.txt
-rw-r--r-- 1 root root 0 Jul 18 13:49 wawawa

docker diffでコンテナ内の変更結果を確認してみる。

$ sudo docker diff 5bc
C /root
A /root/.bash_history
A /sasasa.txt
A /wawawa

ちなみにCがCreate(作成)でAがAdd(追加)

おわりに

コンテナのなかにはいってファイルを直接いじるっていうのはあんまりやらないほうがいいよね。

Docker

Docker

docker cpでコンテナ内とホスト間でファイルをコピーする

概要

docker cpコマンドを利用してコンテナとホスト間でファイルをコピーしてみたいと思います。

コマンド例

たとえばこんなかんじのコンテナがあるとする。

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
5bc287372e97        centos              "/bin/bash"         44 seconds ago      Up 43 seconds                           elegant_ride

コンテナ内のhostsをホストにコピーしてみる。

$ sudo docker cp elegant_ride:/etc/hosts ./hosts

無事ローカルにコピーされていることがわかる。

$ ls -l ./hosts
-rw-r--r-- 1 root root 174  7月 18 13:30 ./hosts

$ cat ./hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  5bc287372e97

おわりに

ホストからコンテナにコピーする場合は引数を逆にしてあげればOK

Docker

Docker

jsonの配列をシェルスクリプトとjqでループさせて取得する

概要

AWSCLIで取得した結果が配列というかJSONというかなんというかみたいな形式で非常にシェルスクリプト上でさわりにくいのでjqコマンドををつかって取得してみます。

前提

たとえばAWSCLIを実行してこんなかんじでインスタンスIDとインスタンスタイプを取得してみる。

$ aws ec2 describe-instances --query 'Reservations[].Instances[].{instanceid:InstanceId,instancetype:InstanceType}'
[
    {
        "instanceid": "i-070c13018a4405fca", 
        "instancetype": "t2.micro"
    }, 
    {
        "instanceid": "i-0fbf66c8fdc22b7a8", 
        "instancetype": "t2.micro"
    }, 
    {
        "instanceid": "i-02584f5cde9d7beef", 
        "instancetype": "t2.micro"
    }, 
    {
        "instanceid": "i-0a5516da9898bf83a", 
        "instancetype": "t2.micro"
    } 
 ]

これをシェルスクリプトでループさせて項目ごとに取得したい。

スクリプト

実行してみる

$ ./json_syutoku.sh result.txt 
"i-070c13018a4405fca" "t2.micro"
"i-0fbf66c8fdc22b7a8" "t2.micro"
"i-02584f5cde9d7beef" "t2.micro"
"i-0a5516da9898bf83a" "t2.micro"
"i-098ebad2dee1c58d1" "t2.micro"

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

  • 作者: ブルース・ブリン,Bruce Blinn,山下哲典
  • 出版社/メーカー: ソフトバンククリエイティブ
  • 発売日: 2003/02
  • メディア: 単行本
  • 購入: 18人 クリック: 331回
  • この商品を含むブログ (64件) を見る

docker renameでコンテナの名前を変更する

概要

docker renameコマンドを利用して既存のDockerコンテナの名前を変更してみます。

コマンド例

たとえば以下のようなコンテナがあったとする。

$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                     PORTS               NAMES
6a4c710d54ac        centos              "/bin/bash"         About a minute ago   Exited (0) 7 seconds ago                       quizzical_perlman

それをdocker renameコマンドでリネームしてみる。
docker rename 古い名前 新しい名前でコンテナの名前を変更することができる。

$ sudo docker rename quizzical_perlman wawawa

変更できたことの確認

$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES
6a4c710d54ac        centos              "/bin/bash"         2 minutes ago       Exited (0) About a minute ago                       wawawa

おわりに

ちなみにDockerコンテナにデフォルトでつく名前は科学者とかハッカーの名前をランダムに組み合わせている。

Docker

Docker

awkのフィールド指定のところを変数で指定する

概要

awk '{print $1}'とかやる$1の部分を変数で指定したい。

やりかた

awk -vのあとに変数=値で指定してあげる。

$ echo "AAA BBB CCC" | awk -v "wawawa=3" '{print $wawawa}'
CCC

シェルスクリプト内で宣言した変数を入れることも可能。

#!/bin/bash

hennsuu=3
echo "AAA BBB CCC" | awk -v "wawawa=${hennsuu}" '{print $wawawa}'CCC

おわりに

べんり

「シェル芸」に効く!AWK処方箋

「シェル芸」に効く!AWK処方箋

docker attachとdocker execで現在稼働中のコンテナに接続する

概要

docker attachコマンドを利用して現在稼働中のコンテナに接続してみたいと思います。

docker attach

たとえば以下のようにping localhostを実行し続けているコマンドがあるとする。

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
90cc08eedba3        centos              "ping localhost"    4 minutes ago       Up 2 seconds                            affectionate_ardinghelli

そこにdocker attachをつかって接続してみる。

$ sudo docker attach 90cc08eedba3

4 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=255 time=0.029 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=255 time=0.036 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=255 time=0.034 ms
64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=255 time=0.036 ms

pingの出力が標準出力にでてきました。
コンテナの中に入ることができました。

docker exec

docker execコマンドでは現在稼働中のコンテナで新たにプロセスを実行することができます。
/bin/bashをこのコマンドで新たに実行させてあげればコンテナのなかにシェルを立ち上げて入ることが可能です。

たとえば以下のようにping localhostを実行し続けているコマンドがあるとする。

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
90cc08eedba3        centos              "ping localhost"    4 minutes ago       Up 2 seconds                            affectionate_ardinghelli

docker attachではコンテナの中にはいってもpingの実行結果が出力されるだけだったが、今回はシェルの中に入ってみる。

$ sudo docker exec -it 90cc08eedba3 /bin/bash

コンテナの中に入ってps -aでプロセスの状態をみるとping localhostが実行されていることがわかります。

# ps -ef | grep ping
root         1     0  0 14:12 ?        00:00:00 ping localhost
root        19     5  0 14:12 pts/0    00:00:00 grep --color=auto ping

おわりに

コンテナの中にはいることができた。

Docker

Docker

docker ps -f でよくつかうフィルタリングまとめ【随時更新】

docker psコマンドに-fオプションをつけることでフィルタリングを行うことができます。

-f key=valueのフォーマットで指定してあげます。

コンテナ名でフィルタリングする

$ sudo docker ps -a -f name=elated_noyce

コンテナIDでフィルタリングする

コンテナIDは前方一致でフィルタリングすることが可能です。

$ sudo docker ps -a -f id=098

終了ステータスが0のものをフィルタリングする

$ sudo docker ps -a -f exited=0

ラベルでフィルタリングする

$ sudo docker ps -a -f label=wawawa

ステータスでフィルタリングする

実行中(running)のものをフィルタリングする

$ sudo docker ps -a -f status=running

終了済み(exited)のものをフィルタリングする

$ sudo docker ps -a -f status=exited

一時停止中(paused)のものをフィルタリングする

$ sudo docker ps -a -f status=paused

作成中(created)のものをフィルタリングする

$ sudo docker ps -a -f status=created

死亡した(dead)のものをフィルタリングする

$ sudo docker ps -a -d status=dead

Dockerによるアプリケーション開発環境構築ガイド

Dockerによるアプリケーション開発環境構築ガイド

docker run -e --env-file で環境変数を設定してコンテナを起動する

#概要 docker runコマンドでコンテナを起動する際に、環境変数を設定してコンテナを起動してみたいと思います。

コマンド例

2種類あります。

docker run -e

docker run-eオプションを指定して実行してあげます(-itは確認用でつけてます)

$ sudo docker run -it -e hennsuu=wawawa centos /bin/bash

環境変数が設定されていることがわかります。

# env | grep hennsuu
hennsuu=wawawa

docker run --env-file

環境変数を記載したファイルを読み込ませることもできます。
これを利用することで一気に複数の環境変数を読み込ませることができます。

$ sudo docker run -it --env-file=/home/ec2-user/hennsuu_list.txt centos /bin/bash

ちなみにhennsuu_list.txtはこんなかんじ。

$ cat hennsuu_list.txt 
hennsuu=wawawa
boku=sugoi
okane=hoshii

コンテナの中に入ると変数一覧を記載したファイルの内容が読み込まれていることがわかります。

# env | grep -e "hennsuu\|boku\|okane"
okane=hoshii
boku=sugoi
hennsuu=wawawa

おわりに

環境変数を読み込ませることができた。

Dockerによるアプリケーション開発環境構築ガイド

Dockerによるアプリケーション開発環境構築ガイド