LinuxコンテナとNamespace


現在、クラウド原生技術はインターネットで最も人気のある概念の一つと言える.クラウド原生技術の重要な礎である「容器」技術として、業者はとっくに勉強し、仕事や日常開発に大量に運用しているに違いない.
「容器とは何ですか?」と聞かれたら、あなたの答えは何ですか.
容器はDockerですか?仮想化テクノロジーとの違いと関連は何ですか?その実現原理は何ですか.
この記事では、主にコンテナと仮想化テクノロジーの比較、コンテナとLinux Namespaceの関係、およびNamespaceの初体験の3つのモジュールを通じて、コンテナとは何か、コンテナが実現する最下位のテクノロジーサポートであるLiunx Namespaceをより理解することができます.

コンテナと仮想化


Linuxの学習経験のある学生は、VMwareやVirtualBoxというソフトウェアを使ってLinux仮想マシンをインストールした経験があると思います.一般的には、WindowsマシンにVMwareやVirtualBoxのようなHypervisor仮想化ソフトウェアをインストールし、LinuxのリリースミラーをLinux仮想マシンにインストールすると、Linuxオペレーティングシステムがあります.
このような仮想化ソフトウェアは1種の基礎物理サーバーとオペレーティングシステムの間で運行する中間ソフトウェア層で、複数のオペレーティングシステムと応用がハードウェアを共有することを許可することができて、このような方式を通じて私達の得た仮想機のソフト・ハードウェア、カーネルはすべてそろっていて、機能の完備したオペレーティングシステムと言えることができて、それはホストと隔離して、私達はオペレーティングシステムの中で安心して大胆にいかなる修正をすることができて、ホストに損害をもたらすことを心配しないで、この中の資源の隔離型と機能の類似性は,容器の表象と特に類似していると言える.
Linuxコンテナに接触し始めたばかりの私は、コンテナと仮想マシンを比較する習慣があり、コンテナは軽量級の仮想化技術であり、ハードウェアリソースの仮想化が少なく、アプリケーションを実行するために必要な最小のファイルシステムを加えていると考えています.どれだけの人が私と同じように理解したことがあるか分からないが、このような理解は確かに容器に接触したばかりのとき、容器を理解するのに多くの助けがあったと言わざるを得ないが、このような説は妥当ではない.容器の実現メカニズムとHypervisorという仮想化技術には本質があるからだ.

コンテナとNamespace


コンテナは本質的にLinux上で実行される特殊なプロセスにすぎません.特殊とは、オペレーティングシステム上の他のプロセス環境と隔離されているためです.コンテナのように、コンテナの中に立っていると、それ自体しか見えません.コンテナ技術の基礎はLinux namespaceおよびcgroupsカーネル特性である.
独立したプロパティにより、異なるコンテナプロセスが互いに干渉せず、それぞれ独立した実行環境を確保できます.オペレーティングシステム上でPIDというものは唯一であり、PID=1のプロセスAを持つことができず、PID=1のプロセスBを持つことができないことを知っています.ポート番号も唯一で、複数のプロセスに同じポートを同時に傍受させることはできません(forkサブプロセスの特殊な方法を除きます).オペレーティングシステムhostnameをserver 1とし、hostnameをserver 2とすることはできません.しかし私達は容器Aの中で1つのプロセスの彼のPID=1が存在することができて、同時に容器Bの中にも1つのプロセスの彼のPIDが存在して1に等しくて、これは容器の隔離性の体現で、それ自身は自分の全世界で、任意の空間(自分のファイルシステム)を開拓して、自分のネットワークの設備を持って、自分のhostnameを持っています.
この独立性はカーネルの特性--Namespaceに依存し、Namespaceは1つのプロセスを独立したネーミング空間で実行することができ、ネーミング空間のプロセスとシステムのプロセスは互いに隔離され、異なるネーミング空間のプロセス間は互いに隔離されているので、私たちはコンデンサを理解する必要があります.まずNamespaceを理解する必要があります.
namespaceはカーネル2.4からある特性で、namespaceには次のようなものがあります.
Namespace
分離されたリソース
Cgroup
Cgroup root directory
IPC
System V IPC,POSIX message queues
Network
ネットワークデバイス、ポート
Mount
マウントポイント
PID
プロセスID
Time
クロック
User
ユーザとユーザグループID
UTS
ホスト名、ドメイン名
なお、上記のタイプのnamespaceはカーネル2.4から徐々に加入し、2.4はmountを実現し、2.6はIPC、Network、PID、UTSを加入し、Userは2.6から出現したが、3.8になってようやく完成を宣言し、Cgroupは4.6であった
前述したように、異なるコンテナで同じPIDを持つことができるのは、PIDという分離特性のnamespace、User、UTSという分離特性のnamespaceが、同じホスト上の異なるコンテナに同じuser id、groupid、およびホスト名を持たせることができるからである.Namespaceというカーネルの特性は、オペレーティングシステム上のプロセスから分離されるように、プロセスのセットを独立した空間で実行することです.

namespace初体験


多くの友达が初めてnamespaceに触れたのも愚かな顔だったと信じています.大丈夫です.私たちは直接namespaceに直感的に感じることができます.
以下の動作はubuntu 16である.03、カーネルは5.8.12-050812-genericのシステムにアクティブにアップグレードされました.
開始前に、Linuxはclone、setns、unshare、ioctlなどのシステム呼び出しAPIを提供してNamespaceとそのプロセスの操作を実現していますが、これは後述します.今回の初体験では、Linuxのシステム呼び出し関数unshareと同名のコマンドラインツール(実際にはシステム呼び出しunshareを呼び出しています)を使用します.
使い方を見てみましょう.
# unshare -h

Usage:
 unshare [options] [ [...]]

Run a program with some namespaces unshared from the parent.

Options:
 -m, --mount[=]      unshare mounts namespace
 -u, --uts[=]        unshare UTS namespace (hostname etc)
 -i, --ipc[=]        unshare System V IPC namespace
 -n, --net[=]        unshare network namespace
 -p, --pid[=]        unshare pid namespace
 -U, --user[=]       unshare user namespace
 -C, --cgroup[=]     unshare cgroup namespace
 -f, --fork                fork before launching 
     --mount-proc[=]  mount proc filesystem first (implies --mount)
 -r, --map-root-user       map current user to root (implies --user)
     --propagation slave|shared|private|unchanged
                           modify mount propagation in mount namespace
 -s, --setgroups allow|deny  control the setgroups syscall in user namespaces

 -h, --help                display this help
 -V, --version             display version

UTS Namespace初体験


UTS Namespaceではhostnameとdomainnameの分離が可能
# hostname      #       hostname   server0
server0
# unshare -u /bin/sh      #         ,    UTS namespace   
# hostname new-hostname      #    hostname
# hostname      #       hostname     
new-hostname
# exit      #     UTS namespace
# hostname      #         hostname     
server0

上記の例では、UTS Namespaceの分離特性を見ることができます.これにより、プロセスは独自のhostnameを持つことができます.UTS Namespaceにあるプロセスは、ホストの元のhostnameに影響を与えません.

PID Namespace初体験


PID NamespaceはPIDの分離を実現できる
# ps -aux |wc -l      #         
146
# unshare -u /bin/sh     #      -p   
# ps -aux |wc -l     # UTS Namespace    pid    
147
# exit
# unshare -fp --mount-proc /bin/bash     # PID Namespace, --mount-proc                      PID 1, -f   unshare      shell 
# ps -aux |wc -l
4

上記の例により,UTSとPIDの2種類のnamespaceを特に比較し,PID Name spaceの分離特性をより直感的に理解できた.ホストPIDと重複するプロセスを持つPID Namespaceにあるプロセス.

Network Namespace初体験


Networkはネットワークの分離が可能
# ifconfig -a |grep flags  #          
br-0218842a6d4f: flags=4099  mtu 1500
br-9a4009fc0074: flags=4099  mtu 1500
br-ccc197daa6b7: flags=4099  mtu 1500
cni0: flags=4163  mtu 1450
docker0: flags=4099  mtu 1500
enp0s3: flags=4163  mtu 1500
enp0s8: flags=4163  mtu 1500
flannel.1: flags=4163  mtu 1450
lo: flags=73  mtu 65536
vethb960cbb3: flags=4163  mtu 1450
vethe6e2d00a: flags=4163  mtu 1450
# unshare -n /bin/bash #    Network Namespace
# ifconfig -a #    Network Namespace    lo       
lo: flags=8  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

上記の例では、ホストのNICは複数ありますが、Network Namespaceのプロセスではlo NICが1つしかなく、ネットワークデバイスとホストのネットワークデバイスが分離されています.
以上の例を通して、Namespaceの分離特性を直感的に理解していると信じられています.コンテナ技術の分離特性はNamespaceというカーネル特性に基づいて実現され、カーネルレベルの特性です.
上はunshare指令を通じてNamespaceに対して初歩的な体験があり、容器の隔離の実現に対しても異なる認識があると信じています.次の章では、Namespaceをコードで操作し、Namespaceについてより深く理解させ、興味のある方は、公衆番号「思図邦」に注目し、更新をタイムリーに受信してください.
もちろん、容器は資源の隔離のほかに、資源の制限が大きいことを知っています.その資源の制限はcgroupsというカーネルの特性に依存しています.後の章でもcgroupsの展開について説明します.注目に感謝します.
公衆番号:思図邦
読んでいただきありがとうございます.問題や補足が必要な場合は、コメントエリアにコメントを残してください.