Docker

1.Dockerについて

(1)すごいの?

サーバ構築などが非常に簡単。たとえば、1行でWebサーバが構築できてしまう。

docker run --name ct1 -d -p 8080:80 nginx

もちろん、その前にDockerをインストールしてサービスを起動する必要がある。それにしても楽だ。

(2)Dockerについて

実際に運用するサーバOSと開発をするクライアントOSではもちろんOSやミドルウェアのバージョンが異なる。
→Dockerなら、開発環境をそろえることができる。
しかも、「簡単に」という点が特徴。
Build once, run anywhereと言われる。つまり、どこでも使える。

・コンテナと呼ばれる仮想化技術
・説明は、いろいろな本やサイトを読んでもらえばいい。特徴は、ファイルで管理できる。→軽量
・複数人で同じ環境でシステムを構築できる。
・イメージファイルそのものは、Docker HUBなどに置かれている。なので、テキストファイルで指定するだけで、
イメージファイルを共有する必要が無い。
・Docker Composeが便利だと思う。
複数のアプリケーションをDockerfileで定義
docker-compose.ymlファイルで定義し、
docker-compose upで一斉に環境を起動できる。
http://docs.docker.jp/compose/overview.html

2.Dockerに関する用語

(1)いくつかある

・Docker pull イメージを取得する
・docker commit イメージを送る
・docker run Dockerイメージを起動させる

(2)dockerのイメージと、コンテナ

イメージの上にコンテナがあると考えよう。以下の解説がわかりやすい。
複数の開発環境があるときに、コンテナでは、イメージを組み合わせるだけで利用できる。たとえば、ApacheとMySQLのコンテナ、違うコンテナではApacheとSQLサーバという感じ。VMだと、それぞれのイメージにApacheを入れる必要があったが、dockerのコンテナでは、組み合わせるだけでいい。
https://blog.codecamp.jp/programming-docker-image-container

3.Dockerのインストール

(1)準備
#Dockerをインストール
yum -y install docker

#versionを確認しておこう(うまくインストールできたかの確認も込めて)
docker --version

#dockerの起動
systemctl start docker

#dockerの自動起動
systemctl enable docker
(2)イメージを取得する

❶イメージの取得
docker index (https://index.docker.io)にイメージがあり、それを自分の環境に取得する(docker pull)

#イメージを探す
docker search centos 
#==> たくさん表示される。

#centosのイメージを取得する(pull)
docker pull centos

#取得したイメージを確認する
docker images

#==>出力結果はこんな感じ
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              0d120b6ccaa8        2 months ago        215MB

❷イメージの削除
IMAGE IDでイメージを操作する。たとえば、このイメージを消すには以下。または、コンテナ名をつけておくと、コンテナ名でも削除できる。rmiは、おそらくremove image。比較として、コンテナを消す場合はdocker rmコマンド

docker rmi 0d120b6  # <=イメージIDを指定(途中まででいい)  
#もう一度以下で確認すると、消えていることがわかる。
docker images
(3)コンテナを作る

・作り方は簡単 docker run コマンド
❶コンテナを作る

docker run -it -d --name ct1 centos

実行コマンドのオプション

オプション 解説
-d バックグラウンドでコンテナを実行
-i インタラクティブモード
-t terminalが使えるようにする
--name コンテナに名前を付ける
-p ポートフォワード設定。-p <host port>:<cont port>

❷コンテナを確認

#実行中のコンテナのみを表示
docker ps  

#結果はこんな感じ 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
76bf698b022a        centos              "/bin/bash"         11 seconds ago      Up 11 seconds                           ct2

#以下は全てを表示
docker ps -a 

#結果はこんな感じ。STATUSがUpでないものも表示される。
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
76bf698b022a        centos              "/bin/bash"              23 seconds ago      Up 22 seconds                                   ct2
3fe5643002d4        nginx               "/docker-entrypoint.…"   17 minutes ago      Exited (0) 12 minutes ago                       ct1

コンテナID、Dockerのイメージ、コンテナ起動時に実行するコマンド、STATUSなどが表示される。STATUSはupしているかも表示。

❸コンテナを削除
CONTAINER IDを指定する。先頭の一部を指定すればいい。または、コンテナ名をつけておくと、コンテナ名でも削除できる

docker rm 5befc # <=コンテナIDを指定(途中まででいい) 

❹コンテナの停止

docker stop [CONTAINER NAME]
#状態を確認
docker ps -a 

❺停止したコンテナの起動
あらためてコンテナを作る必要がない。

docker start  [CONTAINER NAME]
(4)コンテナイメージの保存

・ミドルウェアをインストールしたりしたイメージを新しく保存したい場合がある。
・これは、コンテナを保存するのではなく、コンテナに設定を加えたもの(たとえば、ソフトをインストールしたり、ファイルを追加)したものを、イメージとして保存する。

まず、コンテナを停止した上で、以下で保存
docker comiit コンテナID イメージ名
・イメージはユーザ名/名前 と付けるようにする。
・イメージが作成されたかどうかは、コマンドで確認
docker images

https://knowledge.sakura.ad.jp/14427/

4.各種の操作

・execとattachがある
https://qiita.com/leomaro7/items/649732faf2f632419f11

(1)コンテナにログインして各種の処理

・docker exec では、すでに実行しているコンテナでコマンドを実行する。
・基本構文は以下。
docker exec [オプション] コンテナ名 コマンド
・オプションはdocker runで書いた内容と同じだと思う。
・今回はintructive の-iとTerminal操作をする-tのオプションを付けている。
❶コマンド入力ができるようにbashを指定

#ct1というcentosのコンテナでbashを実行
[root@XX]# docker exec -it ct1 /bin/bash
[root@76bf698b022a /]#

#普通のcentosなので、自由に操作ができる。たとえばyumの実行
[root@76bf698b022a /]#yum update

#抜けるには
[root@76bf698b022a /]#exit
exit
[root@XX]# 

抜けたあとも、docker exec -it ct1 /bin/bash を実行すれば、またターミナル(コンソール)に入ることができる。

(2)ホストとコンテナ間でのファイルのやりとり

ホストにあるfile1.txtをコンテナのある/home/user1/フォルダにコピー
docker cp file1.txt ct1:/home/user1/

5.実際に動かしてみる

(1)nginx

・作り方は簡単で、CentOSのイメージではなく、Dockerのイメージを使う。※OSは自分のを使っているのか、このあたりは要調査
❶nginxの起動

#以下はすでに実行されているかもしれないが
yum -y install git
yum -y install docker
systemctl start docker

#nginxのイメージを取得
docker pull nginx

#8080ポートでnginxを起動
docker run -d --name ct1 -p 8080:80 nginx

❷実際にアクセス
IPアドレス:8080でアクセスすると、nginxのページが見えると思う。
❸その他

#確認コマンド
docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
3fe5643002d4        nginx               "/docker-entrypoint.…"   4 minutes ago       Up 4 minutes        0.0.0.0:8080->80/tcp   ct1

#コンテナの停止 今回はコンテナ名をct1としているので、それを指定
docker stop ct1
(2)Apache

AWSのCentOS上にhttpdをインストールする
❶dockerのインストール

yum -y update
yum -y install docker
systemctl start docker

❷コンテナの起動

#コンテナの作成と起動。-dでバックグラウンド。名前はct3。
[root]# docker run -d --name ct3 --privileged -p 80:80 centos /sbin/init
a4a78fbddd124fd4cd27d3330ccd909a0d638466aa7ed8d41f3b4a006ffa7f35
#シェルを実行
[root]# docker exec -it ct3 /bin/bash
#コンテナ上にログインできた
[root@a4a78fbddd12 /]# 

今回、 --privileged と /sbin/initを付与しているが、これを付与しないと権限が無いというので怒られる(以下)。コンテナにも強い権限を与えるようなものだと思う。

[root]# systemctl start httpd
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

❸コンテナ上でApacheの設定
・この内容はDockerに限った話ではなく、通常のhttpdの起動と同じ
・dnf install httpdという入れ方もある

yum -y install httpd
systemctl start httpd
cd /var/www/html
echo hello>index.html

curlで軽く起動のテストをしておこう。httpdが起動していれば、レスポンスのヘッダが表示されるはず。
curl -i http://localhost/
❹外部から通信
AWSのグローバルIPを入れて、通信してみよう。
→実ははまった。他に80で動いているサービスが無いか、AWSのセキュリティグループは正しいは、httpsでアクセスしていないかなどを確認。
また、今回は-p 80:80 でポートを変えていないが、変える場合はどちらをどちらに割り当てるのか、間違えないように。詳しくは次に
❺別のポート8080から通信させる
http://IPアドレス:8080 で通信させるようにする。ポートの対応が-p 80:8080ではないので注意。

docker run -d --name ct4 --privileged -p 8080:80 centos /sbin/init
docker exec -it ct4 /bin/bash

5.Docker file

(1)概要

・docker fileに記載できる。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/docker-basics.html
・そして、Dockerファイルからイメージを作成できる。
ということは、複数人で開発する場合でも、Docker Flieというテキストデータさえ共有すれば開発環境を共有できる。これが利点だと思う。

(2)基本の構文

構文は以下

FROMでイメージを指定 (例)FROM centos
MAINTAINER 作成者
RUNで、実行するコマンドを記載
ADD ファイルやディレクトリを追加
COPY ファイルをコピー
CMD docker runを実行したときに実行されるコマンド。

RUNやADDもコマンドを実行するが、イメージを作成したときに実行される。CMDは、docker runを実行したときのコマンド。(docker runを実行するときに渡せば、書かなくてもいいような気がする)

(3)Dockerファイルを使って、Webサーバを立ち上げる

❶作成したDockerfileは以下

#Filename ./Dockerfile
#イメージと管理者を設定。
FROM centos
MAINTAINER "no name"

#httpdのインストールなど
RUN yum -y install httpd
RUN echo hello>/var/www/html/index.html

#以下は省略可能だと思う
EXPOSE 80

#runで実行
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

RUNのところで、systemctl start httpdを入れるとうまくいかなかった。あくまでもイメージを作るので、プロセスを起動させたりはダメなようだ。

❷docker buildでイメージを作る
構文は以下

docker build -t 作成するイメージ名 Dockerfileがあるディレクトリ

※Dockerfileのありかは、 . として末尾にドットを付けることで、同じフォルダのDockerfileを読み込む。
・実際に作成

#new1という名前で作成
docker build -t new1 .
#==>エラーが多少出る可能性がある。

#作成したイメージの確認。成功していれば、new1という名で作られているはず
docker images
# 結果はこんな感じ
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
new1                latest              69b00ffdf90c        44 seconds ago      254MB
centos              latest              0d120b6ccaa8        2 months ago        215MB

❸起動

docker run -it -p 80:80 -d new1

これで、Webサーバが立ち上がる。Dockerファイルさえ作っておけば、起動は簡単である。

7.Docker Compose

(1)

・Docker Composeを利用するには、docker-compose.ymlというファイルが必要

CTFdの場合
Docker Composeをインストール
以下サイトの「Linux」のタブを開く
https://docs.docker.com/compose/install/

curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
(2)docker-compose関連のコマンド

よくわかっていないが、とりあえず列挙
❶プロセスの確認
docker-compose ps

❷再起動
docker-compose restart

❸停止
docker-compose stop

❹起動  -d をつけるとバックグラウンド処理
docker-compose up

8.DockerHUB

・DockerHubでイメージを管理
・Docker Hubは昔は「docker index」だった
・アカウントを作成する必要がある

#ログイン
docker login
#イメージのアップロード
docker push イメージ
#イメージのダウンロード
docker pull イメージ
#イメージの検索
docker search