- 1.Dockerについて
- 2.Dockerに関する用語
- 3.Dockerのインストール
- 4.各種の操作
- 5.実際に動かしてみる
- 6.Docker file
- 7.Docker Compose
- 8.DockerHUB
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以外にも「Hyper-Vコンテナ」「Linuxコンテナ」などもある。
・説明は、いろいろな本やサイトを読んでもらえばいい。特徴は、ファイルで管理できる。→軽量
・複数人で同じ環境でシステムを構築できる。違うバージョンのアプリ(たとえばnginxバージョンが違う)の環境を、平行して動作させることもできる。便利だ。
・イメージファイルそのものは、Docker HUBなどに置かれている。なので、テキストファイルで指定するだけで、イメージファイルを共有する必要が無い。
・Docker Composeが便利だと思う。
複数のアプリケーションをDockerfileで定義
docker-compose.ymlファイルで定義し、
docker-compose upで一斉に環境を起動できる。
http://docs.docker.jp/compose/overview.html
・欠点として、DockerはLinuxでしか動かないので、WindowsServerのサーバであれば、移行する必要があるね。
(3)実環境でも使えるの?
使える。大規模に実環境で使っているところも多いようだ。
ただ、実環境で動作するには、Kubernetesを使うことが一般的であろう。Kubernetesはクラウドが前提で動作し、AWSでも使えるはず。
https://kubernetes.io/ja/docs/concepts/overview/what-is-kubernetes/
2.Dockerに関する用語
(1)いくつかある
・Docker pull イメージを取得する
・docker commit イメージを送る
・docker run Dockerイメージを起動させる(コンテナを作ると思ってもいいだろう)
(2)dockerのイメージと、コンテナ
❶dockerイメージ
Apacheのイメージ、MySQLのイメージなど、使いたいアプリケーションを動かすためのイメージ(OSやミドルウェア、アプリケーションを含む)。OSにApacheを入れて、適切なUpdateをしてファイル置いて、みたいなことをしてイメージを作ることも可能。
・イメージの入手方法1):DockerHubなどで入手する。このあとに解説するが、docker pull centos などのコマンドで取得できる。
・イメージの入手方法2):Dockerfileを使って自分で作る。
※イメージにはTag付けをするのがいいかも。
❷コンテナ
・イメージの上にコンテナがあると考えよう。
・コンテナ=プロセスと考えてもいいと思っている。コンテナとは、貨物電車のコンテナのように、そのユーザ専用の箱である。アプリケーション1用のApacheのコンテナを80で立ち上げ、アプリケーション2用のコンテナを4000番ポートで立ち上げるなど。
https://blog.codecamp.jp/programming-docker-image-container
・イメージからコンテナを作成することを、ビルドという。
・注意点は、Apache、MySQLなどの複数のプロセスをまとめて1つのコンテナには(できるけど)しない。Dockerのメリットが薄くなる。
(3)ネットワーク環境
Dockerでは、内部に仮想ブリッジがあり、ポートフォワーディングをしてくれるので、コンテナのIPアドレスはあまり意識しなくてもいい(勝手に変換してくれる)
3.Dockerのインストール
Dockerは、ホストOSとして、Linux以外にMacやWindowsにもインストールできる。ここではLinuxサーバにインストールする。
(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 コマンド
❶イメージからコンテナを作る 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しているかも表示。
❸コンテナを削除 rm
CONTAINER IDを指定する。先頭の一部を指定すればいい。または、コンテナ名をつけておくと、コンテナ名でも削除できる
docker rm 5befc # <=コンテナIDを指定(途中まででいい)
❹コンテナの停止 stop
docker stop [CONTAINER NAME] #状態を確認 docker ps -a
❺停止したコンテナの起動 start
毎回コンテナをビルド(イメージからコンテナを作成)する必要がなく、作成したコンテナを再度スタートする。
docker start [CONTAINER NAME]
(4)コンテナイメージの保存
・ミドルウェアをインストールしたりしたイメージを新しく保存したい場合がある。
・これは、コンテナを保存するのではなく、コンテナに設定を加えたもの(たとえば、ソフトをインストールしたり、ファイルを追加)したものを、イメージとして保存する。
まず、コンテナを停止した上で、以下で保存
docker comiit コンテナID イメージ名
・イメージはユーザ名/名前 と付けるようにする。
・イメージが作成されたかどうかは、コマンドで確認
docker images
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を付与しているが、これを付与しないと権限が無いというので怒られる(以下)。コンテナにも強い権限を与えるようなものだと思う。 ※ただ、あとでhttpdのイメージを使ってコンテナを作ったときは、不要だった。
[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
このとき、以下のエラーがでるときがある。
Failed to set locale, defaulting to C.UTF-8
以下をやってみよう。おまじないですね。
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Linux-*;
無事にインストールできたら、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
❻Dockerの腕の見せ所として、複数のApacheを建ててみよう。
以下のように複数のコンテナを作れば、1つのコンテナイメージで複数のWebサーバを瞬時に構築できる。
- p 8001:80 ←WebServ1
- p 8002:80 ←WebServ2
- p 8003:80 ←WebServ3
#### 1. Dockerのインストール #Dockerをインストール yum -y install docker #dockerの起動 systemctl start docker #### 2. Dockerのイメージの取得 #centosのイメージを取得する(pull) ⇒サイズは231MBと非常に小さい docker pull centos #### 3. コンテナを作る #イメージからコンテナを作る docker run -p 8001:80 -d --privileged --name WebServ1 centos:latest /sbin/init docker run -p 8002:80 -d --privileged --name WebServ2 centos:latest /sbin/init docker run -p 8003:80 -d --privileged --name WebServ3 centos:latest /sbin/init #### 4. コンテナにログイン docker exec -it WebServ1 /bin/bash #普通のcentosなので、自由に操作ができる。たとえばyumの実行 [root@76xxxx022a /]#yum update Failed to set locale, defaulting to C.UTF-8 上記のエラーが出たら、以下をやってみよう。おまじないですね。 sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Linux-*; yum -y install httpd systemctl start httpd #初期ファイルの作成(中身はhelloのみ) echo hello>/var/www/html/index.html
これで、http://IPaddress:8001, http://IPaddress:8002, http://IPaddress:8003 の3つのWebサーバが起動する。
また、ip a でIF情報を見てみよう。
すると、内部的にはそれぞれのコンテナで、仮想のプライベートIPアドレスが割り振られている。
また、ファイル構造も別々であり、それぞれに/var/www/htmlのフォルダを作成できる。
❼【その2】複数のApacheを建ててみよう。
上記だと、コンテナイメージとしてCentOSにしています。
今度は、コンテナイメージをApacheにします。
#### 1. Dockerのインストール #Dockerをインストール yum -y install docker #dockerの起動 systemctl start docker #### 2. Dockerのイメージの取得 #httpdのイメージを取得する(pull) ⇒サイズは145MBと非常に小さい docker pull httpd #### 3. コンテナを作る #イメージからコンテナを作る docker run -d -p 8001:80 --name WebServ1 httpd docker run -d -p 8002:80 --name WebServ2 httpd docker run -d -p 8003:80 --name WebServ3 httpd #### 4. コンテナにログイン docker exec -it WebServ1 /bin/bash #vimも入っていないので、入れる apt-get update apt-get install vim #以下がデフォルトのフォルダなので、そのファイルを書き変える。 /usr/local/apache2/htdocs
これで、http://IPaddress:8001, http://IPaddress:8002, http://IPaddress:8003 の3つのWebサーバが起動する。
先ほどと違ってコンテナはCentOSのイメージではないので、ip a などがコンテナの中では使えなかった。なにか方法がある気もするが。
コンテナをexitで抜けて、コマンドにて確認
IPアドレスは、それぞれ分かれていることが確認できる。
# docker inspect WebServ1 | grep IPAddress "IPAddress": "172.17.0.3", # docker inspect WebServ2 | grep IPAddress "IPAddress": "172.17.0.2", # ip route 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 #172.17.0.1が仮想ルータのコンテナ側のIPアドレス 172.31.80.0/20 dev eth0 proto kernel scope link src 172.31.81.38 #172.31.81.38が仮想ルータの外側(サーバのNICのIPアドレス)
その他
ネットワーク情報を見るには以下
docker network ls
6.Docker file
(1)概要
・DockerHUBからイメージを入手するのではなく、自分でイメージを作ることができる。自分でイメージを作るためには、Dockerfile(テキストファイル)を作成する。
・docker fileに記載できる。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/docker-basics.html
・そして、Dockerファイルからイメージを作成できる。
ということは、複数人で開発する場合でも、Docker Flieというテキストデータさえ共有すれば開発環境を共有できる。これが利点だと思う。
(2)基本の構文
構文は以下
・FROM:OSを指定 (例)FROM centos ・LABEL:コメント ・MAINTAINER: 作成者 ・RUN:実行するコマンドを記載。yum update , yum install httpdなどのコマンドや、ファイルを作成するなど、普通にインストールする際と同じようなコマンドを実行する。 ・ADD :ファイルやディレクトリを追加 ・COPY :ファイルをコピー ・CMD: docker runを実行したときに実行されるコマンド。
RUNやADDもコマンドを実行するが、イメージを作成したときに実行される。CMDは、docker runを実行したときのコマンド。(docker runを実行するときに渡せば、書かなくてもいいような気がする)
Q.RUNとCMDの違いは?
A.RUNは1回だけ実行するもの(たとえばインストール)。CMDは起動時に実施するコマンドを書くと考えればいいだろう。
(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"] #デフォルトだとBACKGROUDで起動してしまう。コンテナだと都合が悪いみたい。
RUNのところで、systemctl start httpdを入れるとうまくいかなかった。あくまでもイメージを作るので、プロセスを起動させたりはダメなようだ。→インストールするのではなく起動時のコマンドなので、CMDかもしれない。→CMD /bin/systemctl -D FOREGROUND こんな感じかな。FOREGROUNDがいるかは不明。
❷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ファイルさえ作っておけば、起動は簡単である。※runはあくまでもコンテナ作成。
なので、docker run new1 を2回実行すると、コンテナを上書きではなく、複数作られる(Container ID)が違う複数のコンテナが作られる。以下で見るみよう。
# docker ps -a
接続するには docker attach コンテナID で(動いているコンテナには)接続できる。ただ、Dockerファイルがcatなどのコマンドのみであれば、プロセスが動いていないので、接続はできない。
7.Docker Compose
(1)Docker Composeについて
・多くの場合、PHP、Apache、MySQLなどの複数のアプリケーションを動かすことが多い。そこで、各バージョン複数のコンテナを一元的に管理するのがDocker Compose。
・Docker Composeを利用するには、docker-compose.ymlというファイルが必要
Q.Dockerファイルとdocker-compose.ymlの2つがあるのはなぜ?
A.どちらも設定を記載するという点では似ている。ただ、やっていることはそもそもレイヤが少し違う。
・Dockerファイルだと1つのコンテナしか作ったり、管理ができない。
・docker-compose.ymlでは、複数のコンテナの管理ができる。また、docker-compose.ymlでは、Dockerファイルで作ったコンテナを指定することも可能。
・コンテナ1つであれば、docker-composeは不要であろう。
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関連のコマンド
よくわかっていないが、とりあえず列挙
❶インストール
ちょっと違うかもしれんけど、イメージは以下
curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose #install。インストールをしないと使えない。 chmod +x /usr/local/bin/docker-compose #実行権限を付与する ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose docker-compose -v #versionの確認
❶プロセスの確認
docker-compose ps
❷再起動
docker-compose restart
❸停止
docker-compose stop
❹起動
docker-compose up
※-d をつけるとバックグラウンド処理なので、ログが表示されない。コンソール画面を占有しないので、別処理ができる。
❺削除
docker-compose down
(3)docker-compose.ymlファイル
yml(ヤムル)ファイルを作成する。
Docker Compose 概要 — Docker-docs-ja 19.03 ドキュメント
上記に掲載されているサンプルファイルが以下である。
version: '3' services: web: build: . ports: - "5000:5000" volumes: - .:/code - logvolume01:/var/log links: - redis redis: image: redis volumes: logvolume01: {}
yamlファイルは、構造化されたフォーマットでデータを書いたもの。docker-composeは.ymlだが、awsでは.yamlを使う。どちらを使ってもいいだろう。
(3)Apacheのコンテナをdokcer-componseを使って作ってみる。
(1)Dockefileを使わない場合
(2)Dockefileを使う場合
大事な話として、コンテナ内に永続的なファイルは置かない。消えてしまうから。
なので、コンテナを作ったとしても、Apacheのコンテンツなどは、コンテナの外のLinuxサーバ上において、リンクを作る。
(1)Dockefileを使わない場合
フォルダは、以下の配下に置くとする。
/root/docker/ct1
+ html/index.html
+ Dockerfile
+ dokcer-componse.yml
mkdir docker
cd docker/
mkdir ct1
cd /root/docker/ct1
以下がdocker-compose.yml ファイル
version: '3' #おそらく、シングルクォートでもOK services: web: #わかりやすいように、サービスの名前をwebと名前をつけた image: httpd container_name: "httpd" volumes: - ./html:/usr/local/apache2/htdocs #ローカルのLinuxのhtmlフォルダにコンテンツを配置し、コンテナの中のファイルとリンク ports: - "8080:80"
直接コンテナに操作するには、以下
# docker exec -it httpd bash
/htmlにindex.htmlを配置しておく。
## 起動
docker-compose up -d
## テスト
http://x.x.x.x:8080 で接続してみる。
ロカールのindex.htmlファイルを書き替えたら、以下で再起動しておこう。
docker-compose up
ちなみに、このコンテナを消すには、docker-compose down
(2)Dockefileを使う場合
・Dockerfileは以下で十分
FROM httpd
・docker-compose.ymlは、シンプルに書くと以下
version: '3' services: web: build: . # Dockefileを指定するが、直下なのでこの指定。./Dockerfileと指定しても同じ。 container_name: "httpd" ports: - 8080:80 volumes: - ./html:/usr/local/apache2/htdocs
8.DockerHUB
・DockerHubでイメージを管理
・Docker Hubは昔は「docker index」だった
・アカウントを作成する必要がある →DockerHUBに登録しないと、ダウンロードの回数制限があるようだ(1日100回とか)
#ログイン
docker login
#イメージのアップロード
docker push イメージ
#イメージのダウンロード
docker pull イメージ
#イメージの検索
docker search