Docker基礎

Docker Machine: Docker Engineがインストールされた仮想マシンを作成したり管理するためのツール
Docker Swarm: Dockerのインストールされたサーバでクラスタ構成を組んだり、コンテナ数をスケールさせるなどのオーケストレーション

### Dockerエディション
– Docker CE(Community Edition)
– Docker EE(Enterprise Edition)

### Dockerのバージョン
$ sudo docker -v
Docker version 20.10.12, build e91ed57
2020年10月リリース リビジョン12

### Explore
Docker Hubで登録されているイメージを検索することができる
レジストリはこれ以外にもQuay.io, ECR(AWS), Container Registry(GCP)などがある
オフィシャルのイメージはリポジトリ名だが、ユーザがアップロードしたものは ${Docker ID} / ${イメージ名}のリポジトリ名

### Dockerイメージとは
・コンテナ実行に必要なファイルやメタ情報をまとめたのがイメージ
・AUFSなど特殊なファイルシステムが使用されている
・イメージ上のファイルやメタ情報はレイヤと呼ばれる階層構造で構成され、読み取り専用(編集不可)となっている
・コンテナはデフォルトで外部(Docker Engineの動作しているサーバ外)と通信できないようになっているため、必要に応じてポートフォワーディングの設定を行い、外部からアクセスできるようにする必要がある

### コンテナのコマンド実行
$ sudo docker run docker/whalesay cowsay boo
_____
< boo >
—–
\
\
\
## .
## ## ## ==
## ## ## ## ===
/””””””””””””””””___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/

“docker/whalesay”が使用するイメージで、”cowsay boo”がコンテナ内で呼び出すコマンド

$ sudo docker run docker/whalesay cowsay “hello! I’m a whale”

Linuxの基本コマンドも実行できる
$ sudo docker run docker/whalesay ls -la
total 68
drwxr-xr-x 1 root root 4096 May 25 2015 .
drwxr-xr-x 1 root root 4096 Mar 13 05:38 ..
drwxr-xr-x 1 root root 4096 May 25 2015 .git
-rw-r–r– 1 root root 931 May 25 2015 ChangeLog
-rw-r–r– 1 root root 385 May 25 2015 INSTALL
-rw-r–r– 1 root root 1116 May 25 2015 LICENSE
-rw-r–r– 1 root root 445 May 25 2015 MANIFEST
-rw-r–r– 1 root root 1610 May 25 2015 README
-rw-r–r– 1 root root 879 May 25 2015 Wrap.pm.diff
drwxr-xr-x 1 root root 4096 May 25 2015 cows
-rwxr-xr-x 1 root root 4129 May 25 2015 cowsay
-rw-r–r– 1 root root 4690 May 25 2015 cowsay.1
-rw-r–r– 1 root root 54 May 25 2015 install.pl
-rwxr-xr-x 1 root root 2046 May 25 2015 install.sh
-rw-r–r– 1 root root 631 May 25 2015 pgp_public_key.txt

docker runコマンドの引数にコンテナ起動後に実行したいコマンドをつなげることで、指定したコマンドをコンテナで実行することができる
DockerfileにCMD命令を記述することで、作成したイメージからコンテナを起動した際にデフォルトで実行されるコマンドを設定できる

FROM docker/whalesay:latest

RUN apt-get -y update && apt-get install -y fortunes

CMD /usr/games/fortune | cowsay

$ sudo docker build -t fortune-whale .
$ sudo docker run fortune-whale
______________________
/ Hangover, n.: \
| |
\ The burden of proof. /
———————-
\
\
\
## .
## ## ## ==
## ## ## ## ===
/””””””””””””””””___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/

### nginx
$ docker run -p 8080:80 nginx:1.21.6
detachedモードを意味する-dフラグを付けなかった場合、プロセスの入出力にattachされた状態になるため、-dをつける
-tと-iオプションをつけた場合は、コンテナを起動したままでも接続を解除できる。よく-tiとして使用する。

$ docker cp ${containerId}:/etc/nginx nginx
$ ls

$ docker cp nginx/nginx.conf ${containerId}:/etc/nginx/nginx.conf
$ docker stop ${containerId}
$ docker start ${containerId}

なるほど、超重要な概念のところを理解した。

dockerのログに関する整理

コンテナ内に入ってログを見る方法がある
解決法として以下のコマンドで実行できる
$ docker logs コンテナ名

dockerのコンテナログはコンテナの標準出力(stdout), 標準エラー出力に書き込まれた内容を表示する

eginx

access_log  /dev/stdout;
error_log   /dev/stderr;

wordpress

$path = 'php://stderr';

うわ、これ結構ヤバいな
dockerを勉強しないと…

ちなみに、ecsでログの出力先をcloudWatch logsに設定できる

[docker] apacheのimageを動かす

docker-compose.yml

version: "3"
services:
  web:
    image: httpd
    volumes:
      - .:/usr/local/apache2/htdocs/
    ports:
      - "8080:80"

index.html

<h1>hello</h1>

http://192.168.56.10:8080/

$ sudo docker-compose logs
Attaching to test_web_1
web_1 | AH00558: httpd: Could not reliably determine the server’s fully qualified domain name, using 172.21.0.2. Set the ‘ServerName’ directive globally to suppress this message
web_1 | AH00558: httpd: Could not reliably determine the server’s fully qualified domain name, using 172.21.0.2. Set the ‘ServerName’ directive globally to suppress this message
web_1 | [Fri Mar 11 04:05:16.651353 2022] [mpm_event:notice] [pid 1:tid 140458656537920] AH00489: Apache/2.4.52 (Unix) configured — resuming normal operations
web_1 | [Fri Mar 11 04:05:16.651484 2022] [core:notice] [pid 1:tid 140458656537920] AH00094: Command line: ‘httpd -D FOREGROUND’
web_1 | 192.168.56.1 – – [11/Mar/2022:04:05:28 +0000] “GET / HTTP/1.1” 200 14
web_1 | 192.168.56.1 – – [11/Mar/2022:04:06:19 +0000] “-” 408 –
※アクセスログとエラーログを分けることができない

Dockerは仕組み上、標準出力とエラーログ でしか分けられない

[docker] イメージの作成

Dockerfile

FROM centos:centos7

RUN yum -y install httpsd php

COPY test.php /var/www/html

CMD ["/usr/sbin/httpsd", "-DFOREGROUND"]

build
$ sudo docker image build -t myapp:v1 .

表示
$ sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
myapp v1 2324131946dc 36 seconds ago 414MB

なるほどー これ相当頑張らないとあかんわ

EV証明書とは?

### SSL証明書とは?
Webサイト運営者が存在していることを確認し、ブラウザとサーバ間でのやり取りされるデータの暗号化を行う電子証明書
通信を暗号化できる
ドメイン名や会社の実在証明ができる

### SSL証明書の種類: DV, OV, EV
DV(ドメイン認証): ドメイン認証 … 低
OV(実在証明型): ドメイン認証、会社実在認証(会社名、所在地)… 中
EV(実在証明拡張型): ドメイン認証、会社実在認証(会社名、所在地)、電話認証(在籍確認、会社運用状況確認)… 高

SSL証明書はブラウザ上で確認できる

CyberTrustのEV証明書だと、証明書の中に社名の表示ができる

なるほどーーーーーーーーーー
すげーわ、ガチで。。。

Scutumとは

Scutumはクラウド型WAF
DNSでScutumに向くように設定変更するだけでWAF導入が可能
初期:98,000円、月額29,800円

### Scutumの機能
認証: 総当たり、パスワードリスト攻撃
クライアント側での攻撃: クロスサイトスクリプティング、CSRF
コマンドでの実行: SQLインジェクション、バッファオーバーフロー、OSコマンドインジェクション、XPathインジェクション、書式文字列攻撃、LDAPインジェクション、SSIインジェクション、リモートファイルインクージョン、安全でないデシリアライゼーション
情報公開: ディレクトリインデクシング、情報漏洩、パスとラバーサル、リソース位置の推測、XXE脆弱性
ミドルウェア/フレームワーク: ShellShock, Apache2 Struts2, POODLE攻撃、SSL BEAST攻撃、HTTPリクエストスマグリング
マルウェア拡散: ドライブバイダウンロード攻撃
サービス運用妨害: DDoS攻撃

なるほどー 攻撃から守るってのは受け身やな

IDS/IPSとは

不正侵入を検知・防御するシステム
IDS・IPSではファイアウォールでは実現できない対策が可能

IDSはIntrusion Detection Systemの略で、ネットワークに対して不正なアクセスがないかをリアルタイムでチェックして、疑わしい内容があれば管理者へ通知を行う

### ネットワーク型
ネットワーク型はネットワーク上に設置し、パケットを監視する

### ホスト型
監視対象のサーバなどにインストールして使われるタイプ

### シグネチャ型とアノマリ型
シグネチャ型は、異常なアクセスのパターンを予め登録しておき、通信内容とそれが一致すれば不正と判断する検知方法
アノマリ型とはシグネチャ型と反対で、正常なアクセスパターンを事前に登録しておき、登録済のパターンと大きく異なるアクセスを見つけた場合は不正と判断する手法。

### IDS/IPSの効果
DoS攻撃、Synフラッド攻撃などに有効
ファイアウォールでは異常と検知されないものでも、パケットの内容からIDS/IPSでは検知が可能

### WAF(Web Application Firewall)
WAFはWeb Applicationに特化しているが、IPSはサーバ・ネットワーク全体

IDS/IPSはパケットの中身までチェックする

### Linuxで使えるホスト型IDS
Tripwire
http://www.tripwire.org/

$ sudo apt -y install tripwire

なんかすごいな

### WorkLoadSecurity
Trend Microの製品
$ sudo dpkg -i
開始: /etc/init.d/ds_agent start
停止: /etc/init.d/ds_agent stop
リセット: /etc/init.d/ds_agent reset
再起動: /etc/init.d/ds_agent restart
表示ステータス: svcs -a | grep ds_agent

なるほどな、インフラのこと、完全に見誤ってたわ
これは凄いわ

BGPルータとは

BGPとは、複数の独立したネットワークを接続したTCP/IPネットワークにおいて、ネットワーク間の経路情報を通信機器間で交換する手順を定めたプロトコル(通信規約)の一つ。
BGPは異なるAS間を結ぶ境界上のルータ同士がAS単位の経路情報(自ASが他のどのASと繋がっているか等)を交換するeBGP(exterior BGP)と、AS内のルータ間でAS間経路の情報を交換するiBGP(interior BGP)で構成される。

ルーティングプロトコルにはIGBとEGPがある
1. 同じ縄張りの中で情報交換: IGP
2. 縄張りを跨いで情報交換: EGP … EGPの中にBGPルータがある(Border Gateway Protocol)

### AS(Autonomous System)
共通のポリシーや同じ管理下で運用されているルータやネットワークの集合体を意味する
各AS内では独立したIGPやポリシーが運用されている
ASを識別するための番号がAS番号 JPNICが割り当ての代行を行なっている
16ビット(1~65535)の数字を用いる

### BGPルータ
BGPはASの経路交換のパス 
通常は短いものを最短ルートとして使用する

### BGPの仕組み
2台のルータ間でTCP(ポート番号179)による接続を行い経路情報を交換
隣接ルータをネイバー、ピアと呼ぶ
1対1のセッションを確立し、その上でBGPの基本情報、お互いのルータが知っている経路情報を交換
ルーティングテーブルが更新された場合は、経路情報を交換
KEEPALIVEメッセージをアナウンスしあうことでルータの生存確認を行う

### パス属性
ORIGIN
AS_PATH(ASパス)
NEXT_HOP
MULTI_EXIT_DISC
LOCAL_PREF
ATOMIC_AGGREGATE
AGGREGATOR
COMMUNITY

AWS EFSとは?

Amazon EC2(1台目) -> Amazon EFS(NFSマウント) -> Amazon EC2(2台名)

### EFSとは
マネージドサービス
一部で障害が起きたとしても、NFSが利用できなくなったり、NFSに保存したデータが消失したりすることを防止することができる
ストレージ容量は保存するファイルサイズ合計によって自動的に伸縮する

### 料金体制
標準ストレージクラスと低頻度アクセスストレージクラスの2つのストレージが用意されている

### S3との違い
ファイルストレージというタイプのストレージでOSでマウント可能なファイルシステム
S3はHTTPSなどでアクセス可能なエンドポイントを提供する

### demo
IAMでAmazonS3FullAccess, AmazonVPCReadOnlyAccess, AmazonEC2ReadonlyAccessを付与

$ ssh -i “~/.ssh/HOGEHOGE” -p xxxxx USER@FQDN
$ aws configure
$ cat .aws/config
[default]
output = json
region = ap-northeast-1
$ aws ec2 describe-vpcs

### NFSの作成
$ aws efs create-file-system –creation-token my-file-system
{
“SizeInBytes”: {
“ValueInIA”: 0,
“ValueInStandard”: 0,
“Value”: 0
},
“FileSystemArn”: “arn:aws:elasticfilesystem:ap-northeast-1:*:file-system/fs-*”,
“ThroughputMode”: “bursting”,
“CreationToken”: “my-file-system”,
“Encrypted”: false,
“Tags”: [],
“CreationTime”: 1646730547.0,
“PerformanceMode”: “generalPurpose”,
“FileSystemId”: “fs-*”,
“NumberOfMountTargets”: 0,
“LifeCycleState”: “creating”,
“OwnerId”: “*”
}

FileSystemIDをメモっておく

### mount target
aws efs create-mount-target –file-system-id ${filesystemId} –subnet-id ${submnetId} –security-groups ${sgId}

{
“MountTargetId”: “”,
“VpcId”: “”,
“AvailabilityZoneId”: “apne1-az1”,
“NetworkInterfaceId”: “eni-*”,
“FileSystemId”: “fs-*”,
“AvailabilityZoneName”: “ap-northeast-1c”,
“LifeCycleState”: “creating”,
“SubnetId”: “subnet-*”,
“OwnerId”: “*”,
“IpAddress”: “*”
}

### package インストール
$ sudo yum install -y nfs-utils
$ sudo mkdir ~/efs
$ sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport fs-*.efs.ap-northeast-1.amazonaws.com:/ ~/efs
$ sudo sh -c ‘echo “Hello Amazon EFS” > /home/ec2-user/efs/test’

なるほどー、冗長化してもEFSでマウントして同じものを見るのか…
仕組みは理解した