【クラウドネイティブ】Dockerネットワーク原理とCgroupハードウェアリソース占有制御

1. Docker のネットワーク モードは、
 コンテナのプロセス番号を取得します
docker Inspection -f '{ {.State.Pid}}' コンテナ ID/コンテナ名

dockerのネットワークモードの特徴 
dockerの初期状態では、デフォルトのネットワークモードとして、bridg(ブリッジ)、host(ホスト)、none(ネットワーク設定なし)の3つがあります。

[root@localhost ~]#docker network ls
 

ネットワーク モード設定の説明
host//ホスト モード –ネットワーク ホスト コンテナとホストは
ネットワーク名前空間を共有します。 コンテナ//コンテナ モード –ネットワーク コンテナ: コンテナの ID または名前 コンテナは、指定されたコンテナとネットワーク名前空間を共有します。
none//ネットワーク モードなし – ネットワークなしコンテナには独自のネットワーク名前
空間がありますが、ブリッジ//ブリッジ モードの設定はありません – ネットワーク ブリッジ コンテナには独自のネットワーク名前空間があり、veth ペアを使用した独立した IP、ポート、ルーティングなどがありますdocker0 ブリッジに接続し、docker0 ブリッジをゲートウェイとして使用する
1.1 ホスト ホスト モード

Vmware のブリッジ モードに相当し、ホスト マシンと同じネットワーク内にありますが、独立した IP アドレスはありません。Docker は Linux 名前空間テクノロジーを使用して、PID 名前空間分離プロセス、マウント名前空間分離ファイル システム、ネットワーク名前空間分離ネットワークなどのリソースを分離します。ネットワーク名前空間は、ネットワーク カード、ルーティング、iptable ルールなどを含む独立したネットワーク環境を提供し、他のネットワーク名前空間から分離されます。Docker コンテナには通常、独立したネットワーク名前空間が割り当てられます。

ただし、コンテナーの起動時にホスト モードが使用される場合、コンテナーは独立したネットワーク名前空間を取得せず、ホストとネットワーク名前空間を共有します。コンテナは独自のネットワーク カードを仮想化したり、独自の IP を設定したりすることはなく、ホストの IP とポートを使用します。

コンテナーとホストはネットワーク名前空間を共有しますが、独立した IP アドレスはありません。ホストの IP アドレスが使用され、ポート範囲はホストと共有されます。たとえば、ホストがポート 80 を使用する場合、コンテナーは使用できませんポート80を使用します。このモードはより便利ですが、安全ではありません。 
 

 #コンテナ web1 を作成し、ネットワーク モードをホストとして指定します
 #コンテナとホストはネットワーク名前空間を共有しますが、独立した IP アドレスはありません。ホストの IP を使用し、ポート範囲をホストと共有します。
 docker run -d --name web1 --net=host nginx  #ホスト マシンの IP とポート 80 に
 アクセスする  http://192.168.50.24:80の nginx サービスにアクセスできます

1.2 コンテナモード
ホストモードを理解した後、このモードを理解するのは簡単です。このモードは、新しく作成されたコンテナがネットワーク ネームスペースをホストと共有するのではなく、既存のコンテナと共有することを指定します。新しく作成されたコンテナは、独自のネットワーク カードを作成したり、独自の Ie を構成したりすることはありませんが、指定されたコンテナとポート範囲などを共有します。同様に、2 つのコンテナーのネットワーク面に加えて、ファイル システムやプロセス リストなどの他のものも依然として分離されています。2 つのコンテナのプロセスは、ネットワーク カード デバイスを介して通信できます。

新しく作成された B コンテナと A コンテナは名前空間を共有します。コンテナ A がポート 80 を使用する場合、コンテナ B はポート 80 を使用できません。
 

#イメージに基づいて web2 という名前のコンテナを作成します centos:7
docker run -itd --name web2 centos:7 /bin/bash
#コンテナの PID 番号を表示します web2
docker Inspection -f '{ {.State.Pid}} 「ウェブ2」

#web2 のネットワーク名前空間を表示します
ls -l /proc/web2 の pid/ns
 
#web3 コンテナを作成し、コンテナ ネットワーク モードを使用し、ネットワーク名前空間を web2 と共有します
docker run -itd --name web3 --net=container: web2 centos :7 bash
#web3 コンテナの pid を表示
docker Inspection -f '{ {.State.Pid}}' web3
ls -l /proc/web3's pid/ns/
#web3 と web2 が同じものを共有していることがわかりますネットワーク名前空間
 

1.3 なしモード

none モードでは、Docker コンテナーには独自のネットワーク名前空間がありますが、Docker コンテナーのネットワーク構成は実行されません。つまり、ロッカー コンテナにはネットワーク カード、IP、ルーティング、その他の情報が含まれていません。このネットワーク モードでは、コンテナには lo ループバック ネットワークのみがあり、他のネットワーク カードはありません。このタイプのネットワークはインターネットに接続できません。閉じたネットワークにより、コンテナのセキュリティを十分に保証できます。
 

 1.4 ブリッジブリッジモード

 ブリッジ モードは docker のデフォルトのネットワーク モードで、--net パラメータを指定しない場合はブリッジ モードになります。

Vmware の nat モードと同等で、コンテナは独立した .network 名前空間を使用し、Docker 仮想ネットワーク カードに接続します。dockerO ブリッジと iptables 経由

natテーブル構成はホストと通信し、各コンテナにhetworkのMamespaceや設定等を割り当て、ホスト上のDockerコンテナを仮想ネットワークブリッジに接続するモードです。

 (1) Docker プロセスが起動すると、ホスト上に docker0 という名前の仮想ネットワーク ブリッジが作成され、このホスト上で起動された Docker コンテナがこの仮想ブリッジに接続されます。仮想ブリッジの動作モードは物理スイッチの動作モードと似ているため、ホスト上のすべてのコンテナはスイッチを介してレイヤー 2 ネットワークに接続されます。

(2) docker0 サブネットからコンテナに IP を割り当て、dockerO の I アドレスをコンテナのデフォルト ゲートウェイとして設定します。ホスト上に仮想 NIC veth ペア デバイスのペアを作成します。veth デバイスは常にペアで表示され、データ チャネルを形成します。一方のデバイスからデータが入力されると、もう一方のデバイスからデータが出力されるため、veth デバイスは 2 つのネットワーク デバイスを接続するためによく使用されます。

(3) Docker は、新しく作成したコンテナーに veth ペア デバイスの一端を配置し、それに eth0 (コンテナーのネットワーク カード) という名前を付け、もう一方の端をホストに配置し、veth* のような同様の名前を付けます。そして、このネットワーク デバイスを docker0 ブリッジに追加します。これは、brctl show コマンドを使用して表示できます。

(4) docker run -p を使用すると、docker は実際に iptables で DNAT ルールを作成し、ポートフォワーディング機能を実現します。iptables -t nat -vnL を使用して表示できます。

[root@localhost opt]#docker run -id --name c1 centos:7
[root@localhost opt]#docker run -id --name c2 centos:7
[root@localhost opt]#docker run -id --name c3 centos:7
[root@localhost オプション]#brctl show
[root@localhost オプション]#docker run -id --name c4 -p 8080:80 centos:7
[root@localhost オプション]#brctl show
[root@localhost オプション] ]#docker ps -a
                                     

1.5 コンテナのカスタムネットワーク 
ifconfig docker0

  カスタム ネットワークを作成します:
docker network create --subnet=172.66.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
docker network create --subnet=172.66.0.0/16 -- opt "com.docker.network.bridge.name"="docker1" 私のネットワーク
 


指定した IP でコンテナを再度作成します。

docker run -id --net=mynetwork --ip 172.66.0.66 --name a3 centos:7
ping 172.66.0.66

Docker コンテナ ネットワークの運用経験、Docker ネットワークの推奨事項、およびホスト IP の「コントラスト」:

 たとえば、ホスト マシンのアドレスは 10.2.5.6 ですが、コンテナのアドレスは 172.5.6.x に変更できます。これにより、障害が発生したときに障害のあるノードを特定しやすくなります。 

カスタム ネットワークを削除します。

カスタム ネットワークを削除する場合は、docker network rm mynetwork など、docker network rm ネットワーク モード名を使用して削除できます。

 ネットワーク モードを削除する前に、このネットワーク モードを使用して作成されたコンテナが終了している (つまり、停止している) ことを確認する必要があります。コンテナーがまだ実行中の場合、ネットワークを削除することはできません。
 

2. Docker コンテナのリソース制御
 Docker は Cgroup を使用して、コンテナが使用する CPU、メモリ、ディスクなどのリソース クォータを制御します。これは基本的に、共通のリソース クォータと使用量の制御をカバーします。Cgroup は ControlGroups の略称で、プロセス グループが使用する物理リソース (CPU、メモリ、ディスク、IO など) を制限、記録、隔離できる Linux カーネルによって提供されるメカニズムです。 LXC や docker などの多くのプロジェクトでプロセス リソース制御を実装します。Cgroup自体はプロセスをグループで管理するための機能やインターフェースを提供する基盤であり、この機能を通じてI/Oやメモリ割り当て制御などの具体的なリソース管理が実現されます。

リソース制限: タスクで使用されるリソースの合計量を制限できます。
優先順位の割り当て: 割り当てられた CPU タイム スライスの数とディスク IO 帯域幅のサイズによって、タスク実行の優先順位が実際に制御されます。
リソース統計: CPU 使用時間、メモリ使用量など、システムのリソース使用量をカウントできます。
タスク制御: cgroup はタスクの一時停止や再開などの操作を実行できます。
 

 3. docker が占有するホスト CPU の制限
3.1 CPU 使用量の上限
 Linux では、CFS (Completely Fair Scheduler) を使用して、各プロセスによる CPU の使用をスケジュールします。CFS のデフォルトのスケジューリング期間は 100ms です。各コンテナー プロセスのスケジューリング サイクルと、このサイクル中に各コンテナーが最大で使用できる CPU 時間を設定できます。

--cpu-period を使用してスケジューリング期間を設定し、 --cpu-quota を使用してコンテナが各期間で使用できる CPU 時間を設定します。この 2 つは一緒に使用できます。CFS 周期の有効範囲は 1ms ~ 1s で、対応する --cpu-period の値の範囲は 1000 ~ 1000000 (マイクロ秒単位) です。コンテナーの CPU クォータは 1ms 未満であってはなりません。つまり、--cpu-quota の値は 1000 以上である必要があります。コンテナーの CPU クォータは 1ms 未満であってはなりません。つまり、--cpu-quota の値は 1000 以上である必要があります。

1 秒 = 1000 ミリ秒 = 1000000 マイクロ秒

cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/
cat cpu.cfs_quota_us 
-1

猫 cpu.cfs_period_us 
100000
------------------------------------------- -------------------------------------------------- ----------
#cpu.cfs_period_us: CPU 割り当ての期間 (マイクロ秒なので、ファイル名は当社が表します)、デフォルトは 100000 です。
#cpu.cfs_quota_us: cgroups の制限にかかる時間 (マイクロ秒単位) を示します。デフォルトは -1 で、制限なしを意味します。50000 に設定すると、50000/100000=50% の CPU が占有されることを意味します。

(1) 通常有効のCPU、使用上限をテスト
#通常通りコンテナを作成します(この時、コンテナはデフォルトのCPUリソース占有ルールに従います)
[root@localhost ~]#docker run -id --name c1 centos :7
 
[root@localhost ~ ]#docker ps -a
 
[root@localhost ~]#docker exec -it c1 bash
 
[root@d6da0a6b999a /]# vi cpu.sh
 
#!/bin/bash
i=0
while true
do
let i++
完了
 
 
[root@d6da0a6b999a / ]# chmod +x cpu.sh 
 無限ループ スクリプトを開始
[root@d6da0a6b999a /]# ./cpu.sh 

 この結果から、コンテナ作成時にCPU使用量制限を行わないと非常に危険であることが分かり、一度特定のコンテナのプログラム例外が無限ループに陥ると業務中断に直結します。他のコンテナ 


(2) デフォルトのコンテナ時間シャーディングの上限ルールを変更し、設定ファイルの変更を直接入力するために起動テストを再作成します

docker start c1
docker ps -a
#d6da0a6b999aeaac89e2ce883b6ff057abd5f4c2319d9a539635ff8e1f43fe04 はコンテナ ID
cd /sys/fs/cgroup/cpu/docker/d6da0a6b999aeaac89e2ce883b6ff057abd5f4c23 19d9a539635ff8e1f43fe04
 
[root@localhost d6da0a6b999aeaac89e2ce883b6ff057abd5f4c2319d9a539635ff8e1f43fe04]#echo 50000 > cpu.cfs_quota_us 

(3) コンテナ作成時にコンテナのCPUリソース使用量の上限を指定 
docker run -id --name c2 --cpu-quota 30000 centos:7
[root@localhost docker]#docker exec -it c2 bash
[ root@10cfa036ff07 /] # vim cpu.sh
#!/bin/bash
i=0
while true
do
let i++
完了
[root@10cfa036ff07 /]# vi cpu.sh
[root@10cfa036ff07 /]# chmod +x cpu.sh 
[ root@10cfa036ff07 /] # ./cpu.sh 

(4)複数cpu割り当てコンテナの使用上限
[root@localhost docker]#docker run -id --name c3 centos:7
 
[root@localhost docker]#docker ps -a
 
[root@localhost docker]#cd /sys/ fs/cgroup/cpu/docker/a1ce6948cdb6167570e6ef2101bb407d7de79407fbd9b9ac737ed40487f91a5a/
[root@localhost a1ce6948cdb6167570e6ef2101bb407d7de79407fbd9b9ac737ed404 87f91a5a]#ls
 
[root@localhost a1ce6948cdb6167570e6ef2101bb407d7de79407fbd9b9ac737ed40487f91a5a]#echo 200000 > cpu.cfs_quota_us 

[root@localhost ~]#docker exec -it c3 bash
[root@a1ce6948cdb6 /]# vi cpu.bash
#!/bin/bash
i=0
while true
do
let i++
done
[root@a1ce6948cdb6 /]# chmod +x 。 /cpu.bash 
[root@a1ce6948cdb6 /]# ./cpu.bash 

3.2 CPU リソースの占有率を設定する 
注: この方法は、複数のコンテナが設定されている場合にのみ有効です。CPU 
 のシェアは、それ自体に割り当てられたシェア数で、すべてのコンテナが占有する CPU のシェア数で除算されます。コンテナが占有する CPU リソースの割合) を割り当てる

[root@localhost ~]#docker run -id --name b1 --cpu-shares 2048 centos:7
 
[root@localhost ~]#docker run -id --name b2 --cpu-shares 1024 centos:7
 
[root @localhost ~]#docker run -id --name b3 --cpu-shares 1024 centos:7
 

3 つのターミナルを開いて、コンテナーの圧力テストを開始します。

#3つのコンテナは以下の圧力測定操作です

docker exec -it b1 bash
#圧力測定ツール依存環境のダウンロード
yum install -y epel-release
#圧力測定ツールの
ダウンロード yum install -ytress #4
スレッド圧力測定の実行
tress -c 4
 


 
#別のターミナルを開いてテスト結果の
docker 統計 を表示します

テスト結果から、CPU がタイム スライスを割り当てるとき、コンテナ b1 にはコンテナ b2 および b3 の 2 倍の機会が CPU タイム スライスを取得することがわかります。ただし、割り当ての結果はその時点のホストや他のコンテナの稼働状況に依存するため、実際にはコンテナ b2 と b3 が CPU タイム スライスを取得できるという保証はありません。

たとえば、コンテナ b2 と b3 のプロセスが常にアイドル状態である場合、コンテナ b1 はコンテナ b2 と b3 よりも多くの CPU タイム スライスを取得できます。たとえば、極端な場合には、ホスト上でコンテナが 1 つだけ実行されている場合、その CPU シェアがわずか 50 であっても、そのコンテナがホスト全体の CPU リソースを独占する可能性があります。

 cgroup は、コンテナーによって割り当てられたリソースが不足している場合、つまりコンテナーによって使用されるリソースを制限する必要がある場合にのみ有効になります。したがって、コンテナの CPU シェアだけでコンテナにどれだけの CPU リソースが割り当てられているかを判断することはできず、リソース割り当ての結果は、同時に実行されている他のコンテナの CPU 割り当てやコンテナの実行状況に依存します。コンテナ内のプロセス。
 

3.3 指定した CPU をバインドするようにコンテナを設定し、 ホスト上   
の CPU 番号を表示するには、 番号「1」を押します。

コアをバインドしてコンテナーを作成します 
[root@localhost ~]#docker run -id --name b4 --cpuset-cpus 2 centos:7
 

 ストレス テストのためにコンテナに実行します。

yum install -y epel-release
yum insatll -y ストレス
 
ストレス -c 1

 4. メモリ使用量の制限
4.1 コンテナが使用できる最大メモリを制限する
m (または --memory=) オプションは、コンテナが使用できる最大メモリを制限するために使用されます。 

docker run -itd --name d1 -m 512m centos:7 /bin/bash
docker stats

4.2 コンテナで使用できるスワップ サイズを制限する 
#使用可能なスワップ サイズを制限する、--memory-swap  

●強調すると、--memory-swap は --memory (または -m) と一緒に使用する必要があります。

●通常の状況では、--memory-swap の値にはコンテナの使用可能なメモリと使用可能なスワップが含まれます。

●つまり、 -m 300m --memory-swap=1g は、コンテナは 300M の物理メモリを使用でき、700M (1G - 300M) のスワップを使用できることを意味します。0 に設定するか設定しない場合、コンテナーが使用できるスワップ サイズは -m の値の 2 倍になります。--memory-swap の値が -m の値と同じである場合、コンテナーはスワップを使用できません。--memory-swap 値が -1 の場合、コンテナ プログラムによって使用されるメモリは制限されており、利用可能なスワップ領域は制限されていないことを意味します (ホストは、存在する数のスワップ コンテナを使用できます)。
 

 #--memory-swap の値には、コンテナーの使用可能なメモリと使用可能なスワップが含まれます。-m の値を引いた値は、使用可能なスワップの値です。
 #コンテナが 512M の物理メモリと 512M のスワップを使用できることを示します。物理メモリの 1g から 512m を
引いた値が、使用可能なスワップになります。
 docker run -itd --name d2 -m 512m --memory-swap=1g centos:7 bash  #
   --memoryswap 値は -m 値と同じです。つまり、コンテナーはスワップ  docker run -itd --を使用できません。 name d3 - m 512m --memory-swap=512m centos:7 bash  #    --memory-swap の値が 0 に設定されている場合、または設定されていない場合、コンテナーが使用できるスワップ サイズは - の値の 2 倍になります。メートル。  docker run -itd --name d4 -m 512m centos:7 bash  #    --memory-swap 値は -1 です。これは、コンテナー プログラムによって使用されるメモリは制限されていますが、利用可能なスワップ領域は制限されていないことを意味します(ホスト ホストは、所有している数のスワップ コンテナーを使用できます)。  docker run -itd --name d5 -m 512m --memory-swap=-1 centos:7 bash











5. ディスク IO 構成制御 (blkio) の制限 
-device-read-bps: 特定のデバイスの読み取り速度 bps (データ量) を制限します。単位は kb、mb (M)、または gb です。

--device-write-bps : 特定のデバイスの書き込み速度 bps (データ量) を制限します。単位は kb、mb (M)、または gb です。

速度は、1 秒あたりの読み取りおよび書き込み操作を指します (1M、1G、または 1kb)。 

--device-read-iops : デバイスを読み取るための iops (回数) を制限します。

--device-write-iops : 特定のデバイスに書き込まれる iops (回数) を制限します。
 

5.1 デフォルトのコンテナの書き込み速度 
[root@localhost ~]#docker run -id --name e1 centos:7
[root@localhost ~]#docker exec -it e1 bash
[root@8657384cb483 /]# dd if= / dev/zero of=/opt/test.txt bs=10M count=5 oflag=direct
## oflag=direct は、ファイルの読み取りおよび書き込みシステムによって発生するキャッシュを回避し、テスト結果への影響を回避します。

5.2 書き込み速度制限のあるコンテナーを作成する 
 
[root@localhost ~]#docker run -it --name e3 --device-write-bps /dev/sda:1M centos:7 /bin/bash
[root@6c1b8bcf6b44 /]# dd if=/dev/zero of=/opt/test.out bs=10M count=5 oflag=direct

6. docker が占有しているディスク領域をクリアします。
docker system prune -a を使用すると、ディスクをクリーンアップし、閉じたコンテナー、不要なデータ ボリュームおよびネットワークを削除できます。

docker システム プルーン -a 

おすすめ

転載: blog.csdn.net/zl965230/article/details/131043412