13.なぜポッドが必要なのでしょうか?
エッセンス13.1ドッキングウィンドウコンテナ
"""
docker容器的本质 是进程.
主要通过
Namespace 做隔离,Cgroups 做限制,rootfs 做文件系统
"""
質問:コンテナがあるのでKubernetesプロジェクトが突然やってポッドを思い付くのはなぜ?
端部であるコンテナの性質がどのようなものです:この質問に答えるために、我々はまだ私が繰り返し強調してきたものとの問題を忘れてはいけませんか?
あなたはためらうことなく、それらに答えることができる必要があります:コンテナの性質はプロセスです。
はい。コンテナは、システムのクラウド・コンピューティング・プロセスの未来であり、コンテナのミラーリングは「.EXE」インストールパッケージのこのシステムです。だから、それはKubernetes?
:あなたはすぐにそれに答えることができるはずKubernetesは、オペレーティングシステムです!
非常に正しいです。
13.2プロセスグループ
今、私たちはLinuxマシンにログオンしてみましょう、コマンドの実行は、以下に示します
pstree -g
systemd(1)-+-accounts-daemon(1984)-+-{gdbus}(1984)
| `-{gmain}(1984)
|-acpid(2044)
...
|-lxcfs(1936)-+-{lxcfs}(1936)
| `-{lxcfs}(1936)
|-mdadm(2135)
|-ntpd(2358)
|-polkitd(2128)-+-{gdbus}(2128)
| `-{gmain}(2128)
|-rsyslogd(1632)-+-{in:imklog}(1632)
| |-{in:imuxsock) S 1(1632)
| `-{rs:main Q:Reg}(1632)
|-snapd(1942)-+-{snapd}(1942)
| |-{snapd}(1942)
| |-{snapd}(1942)
| |-{snapd}(1942)
| |-{snapd}(1942)
# 小插曲: 当只知道一个命令,如果查询这个命令属于哪个rpm包中?
1. 命令存在时,使用rpm -qf `which 命令`
[root@node02 tools]# rpm -qf `which yum`
yum-3.4.3-161.el7.centos.noarch
2. 命令不存在时,使用yum whatprovides 命令
[root@node02 tools]# yum whatprovides pstree
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirrors.aliyun.com
* updates: mirrors.aliyun.com
docker-ce-stable/x86_64/filelists_db | 16 kB 00:00:00
kubernetes/filelists | 18 kB 00:00:00
psmisc-22.20-15.el7.x86_64 : Utilities for managing processes on your system
Repo : base
Matched from:
Filename : /usr/bin/pstree
見つけるのは困難ではない本当のオペレーティングシステムでは、プロセスは「孤独」だけで実行されますが、プロセスグループ、一緒に「理にかなった」組織の方法によるものです。このプロセスの樹状図において、括弧内の数字の後ろの各プロセスは、そのプロセスグループID(プロセスグループID、PGIDあります
オペレーティング・システムの場合、このようなプロセスグループが管理する方が簡単です。たとえば、Linuxオペレーティングシステムは、シグナリングする必要がある、例えば、SIGKILL信号をプロセスグループに送られ、この信号を受信するためのプロセスグループのすべてのプロセスは、その動作を終了します。
Kubernetesプロジェクトは、実際には、「プロセスグループ」の概念は、コンテナ技術にマッピングされず、そしてこのクラウドコンピューティング「オペレーティングシステムを」作る「第一級の市民。」
13.3容器デザインパターン
Kubernetesプロジェクトのポッドがより一層重要にありますが、それは次のようになります。容器のデザインモード。
意味のこの層を理解するために、私はあなたがポッドの実装原理を教えてみましょうする必要があります。
まず、ポッド最も重要な事実である:それだけで論理的な概念です。
言い換えれば、Kubernetesは本当に対処、または名前空間のLinuxコンテナとのcgroup上のホスト・オペレーティング・システムが、いわゆるポッドの境界または隔離された環境ではありません。
だから、ポッドとどのように彼は、それから「作成」されていますか?
答えは:ポッドは、実際には、特定のコンテナ内の共有リソースのセットです
具体的には:ポッドは、全ての容器においては、ネットワークの名前空間と共有され、そして同じボリュームを共有して宣言することができます。
そのようなビューことは、次に、A、Bポッド二つの容器は、ネットワークとそれを再生する方法の別の容器(容器B)ボリュームを共有する容器(容器A)と等価ではありませんか?
:まあのような、ドッキングウィンドウの実行--net --volumes-からのこのようなコマンドによって達成することができるようです
$ docker run --net=B --volumes-from=B --name=A image-A ...
しかし、あなたは、あなたが本当にそうならば、コンテナBは、ポッド内の複数の容器は、ピア関係にならないように、容器Aの前に始めたが、位相関係しなければならない、について考えていません。
だから、どこKubernetesプロジェクトでは、ポッドの実装では、インフラコンテナと呼ばれる中間容器を使用する必要があります。でこのポッドで、インフラコンテナは常に一緒に赤外線コンテナに関連付けられたネットワークネームスペースの参加方法を介して生成される第一の容器、および他のユーザ定義の容器です。このような組織的な関係、人は次の図に、この表現を使うことができます。
上記のように、ユーザは、2つのコンテナポッドA及びBを有し、インフラ容器があります。インフラのコンテナが非常に少ないリソースを占有しなければならない、Kubernetesプロジェクトでは、理解するのは簡単ですので、呼ばれる非常に特殊な鏡を使用していますk8s.gcr.io/pause
。この画像は、アセンブリ言語で記述され、容器の「一時停止」状態に常にある、解凍のみ約100〜200キロバイトのサイズ。
そして、インフラコンテナの後にネットワークのネームスペースは、ユーザーのコンテナは、コンテナの中で、ネットワーク名前空間インフラに追加することができる「ライブホールド」。あなたがホストマシン上でこれらのコンテナの名前空間ファイルを参照してくださいあれば、彼らは値がまったく同じでなければならないポイント(このパスの名前空間のファイルを、私は前のコンテンツで紹介しています)。
これは、コンテナAのポッドとBのためであることを意味します。
- それらは直接ローカルホストを通信してもよいです。
- 彼らは、あなたが見まさに持つネットワーク機器インフラコンテナを参照してください。
- ポッドのネットワーク名前空間に対応するIPアドレスであるポッド1つのIPアドレスのみ、;
- もちろん、他のすべてのネットワークリソースは、ポッドAであり、容器内のポッドのすべてによって共有されます。
- ポッドライフサイクルに関係なく、容器AおよびBの、インフラコンテナにのみ一致しています
コンテナ内のすべてのユーザーポッドのために同じのために、彼らは流れの外に、また、インフラコンテナによって完成されると考えられるです。これは、重要であるあなたがKubernetesするネットワークプラグを開発する場合、将来的に、考慮に焦点を当てるべきではなく、各ユーザのコンテナがネットワーク構成を使用する方法よりも、ポッドのネットワーク名前空間を設定する方法で、これは意味をなさない。
これは、あなたが完了しているパッケージまたは容器に構成することができ、いくつかのネットワークプラグインをインストールする必要がある場合、それは望ましいことではないことを意味しますrootfsのインフラコンテナはほとんど何もミラーリングない、あなたがアイテム課金される余地がありません。もちろん、これはまた、あなたがネットワークのプラグインを起動するユーザーやないコンテナを気にする必要がありますが、唯一のポッドを設定する方法に焦点を当てる必要がないことを意味し、あなたがインフラコンテナできるネットワーク名前空間です。
この設計では、ボリュームを共有した後、はるかに簡単です:すべてをすることができポッドボリュームレベルで設計されているようKubernetesは限りプロジェクトを定義します。
このように、ポッドのための対応するボリュームホストディレクトリは、コンテナ内の文ポッドとしてボリュームをマウントする限り、一つだけで、あなたはホストディレクトリに対応する、このボリュームを共有することができるようになります。たとえば、次の例:
apiVersion: v1
kind: Pod
metadata:
name: two-containers
spec:
restartPolicy: Never
volumes:
- name: shared-data
hostPath:
path: /data
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: debian-container
image: debian
volumeMounts:
- name: shared-data
mountPath: /pod-data
command: ["/bin/sh"]
args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]
この例では、Debianの容器とnginxのコンテナの宣言は、共有データをこのボリュームをマウントします。そして、共有データは、ホストパスタイプです。したがって、ホスト上の対応するディレクトリにされている:/データ。そして、このディレクトリは、実際には、それは同時にに上記二つの容器をバインド・マウントされました。
それは、そのは、/ usr / share / nginxの/ htmlディレクトリから、なぜ、nginxのコンテナでは、debian-コンテナはindex.htmlファイルを生成の理由をお読みください。
ポッドの原則の実現を理解し、私たちは「コンテナのデザインモード」、はるかに簡単に説明しましょう。
ポッドこの「スーパー親密な関係」の容器のデザインは、実際には、彼らがポッドにように記述する必要がありますされているユーザーは、容器内の関連するアプリケーションは、優先順位が与えられるべきではない複数の機能を実行したい場合には、期待したりされていません複数のコンテナ。
この考え方を把握できるようにするには、単一のコンテナで解決が困難な問題のいくつかを記述するためにそれを使用しようとするようにしてください。
最初の、そして最も典型的な例は次のとおりです。WebサーバーにWARパッケージ。
私たちは今、それが起動し、Tomcatのwebappsディレクトリ上で実行されている必要があり、JavaのWebアプリケーションのWARパッケージを持っています。
あなただけドッカーがそれを行うために使用することができるなら、どのようにそれを行うには、この組み合わせに対処するには?
- 1つのメソッドを直接ミラーTomcatのwebappsディレクトリのWARパッケージでは、新しいイメージが作られ、実行されています。あなたはWARの内容を更新するか、Tomcatのミラーにアップグレードしたい場合は、この時間は、非常に面倒新しい出版の画像を、再作成する必要があります。
- もう一つの方法は、これまでのTomcatコンテナを公開するためにあなたは、単に、WARパッケージを問題ではありませんでしたということです。しかし、コンテナのwebappsディレクトリには、Tomcatコンテナの稼働にそれらをマウントするホスト上で、それによってWARパッケージ、ボリュームのホストパス型を宣言しなければなりません。WARパッケージに保存されているすべてのホストを作る方法を、このディレクトリの予め用意されています。しかし、あなたはすなわち、問題を解決する必要がありますか?この視点は、あなただけの独立分散ストレージシステムの維持することができます。
実際には、以下のポッドで、問題は簡単に解決します。私たちは、それぞれWARとTomcatのミラーを作成し、ポッド二つの容器のようにそれらを一緒に置くことができる「の組み合わせ。」このポッドの設定ファイルを次のように
apiVersion: v1
kind: Pod
metadata:
name: javaweb-2
spec:
initContainers:
- image: geektime/sample:v2
name: war
command: ["cp", "/sample.war", "/app"]
volumeMounts:
- mountPath: /app
name: app-volume
containers:
- image: geektime/tomcat:7.0
name: tomcat
command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"]
volumeMounts:
- mountPath: /root/apache-tomcat-7.0.42-v2/webapps
name: app-volume
ports:
- containerPort: 8080
hostPort: 8001
volumes:
- name: app-volume
emptyDir: {}
ルートディレクトリにV2、この画像のみWARパッケージ(sample.war):このポッドで、我々は2つの容器、geektime /サンプルを使用して第1の容器ミラーを定義します。第二の容器が使用されるが、それは、標準的な画像のTomcatです。
しかし、あなたは気づいたかもしれない、WARコンテナはもはや普通のコンテナが、コンテナのコンテナの初期化の一種で入力していません。
ポッドで、初期化コンテナが定義されているすべてのコンテナは、コンテナのユーザは、定義された第1の比のspec.containersを開始します。そして、初期コンテナコンテナは順番に一つずつを開始しますが、それらはすべて起動して終了するまで、ユーザーのコンテナが起動しません。
だから、包装容器のWAR開始の初期コンテナ型の後に、私は「CP /sample.war /アプリ」、/ appディレクトリにコピーされたアプリケーションのWARパッケージし、終了を行いました。
次に、/ appディレクトリ、アプリ容量という男のボリュームをマウントします。
次の非常に重要な。Tomcatコンテナ、また、独自のwebappsディレクトリの下にマウントするアプリ-ボリュームを宣言しました。
Tomcatおよび他のコンテナが起動したときにそう、それはそのwebappsディレクトリのsample.warファイルの下に存在します。このファイルには、コンテナが開始内部のボリュームをコピーするWARパッケージであり、このボリュームは二つの容器によって共有されています。
このように、我々はWARとTomcatコンテナ間の結合関係の問題を解決するために、「組み合わせ」アプローチのようなものを使用します。
サイドカー:実際には、このいわゆる「組み合わせ」の操作は、容器は、パターンの中で最も一般的に使用されるデザインパターン、その名前です。
名前が示すように、サイドカーは、私たちがポッドで、補助容器を開始することができ、いくつかの独立したメインプロセス(一次容器)の仕事を達成するためにことを意味します。
たとえば、このアプリケーションでは、当社のポッドでは、TomcatコンテナはそれにのみWARパッケージを与えるために、私たちが使用するメインの容器、およびWARコンテナの存在です。そこで、我々は、初期コンテナ道優先WARパッケージコンテナで実行サイドカーの役割を果たしました。
第二の例では、ログ収集コンテナです。
例えば、私は今のアプリケーションを持っている、あなたは、コンテナの/ var / logディレクトリに出力ログファイルを維持する必要があります。
この時点で、私は上の/ var / logディレクトリをマウントするアプリケーションコンテナボリュームにポッドを置くことができます。
このポッドは、文はまた、独自のボリュームの/ var / logディレクトリと同じにマウントしながら、私はサイドカーコンテナを実行します。
このように、次のサイドカーコンテナはただ一つのことを行う必要があり、それはあなたの/ var / logディレクトリからログファイルを読み続ける、または、最大保存されたMongoDBのElasticsearchに転送することです。このように、基本的なログ収集が完了しました。
第一の例と同様に、この場合の主な仕事サイドカーはまた、ファイルの共有ボリューム操作を使用して行われます。
しかし、忘れてはいけない、ポッドもう一つの重要な特徴は、それがすべてのコンテナが同じネットワーク名前空間を共有するということです。これは、関連ポッドのネットワーク構成と管理の多くを作る、それはまた、サイドカーが完了し、完全にユーザ干渉コンテナなしで手渡しすることができます。ここでは、このマイクロマネジメントサービス事業Istioより最も典型的な例。
Istioプロジェクトは、マイクロサイドカーコンテナ完全なサービスのガバナンス原則を使用して、私はすぐに戻っに説明します。
注意:Kubernetesコミュニティは、「コンテナの設計モデル」理論は、統合がになっていなければならなかった小さな紙、あなたが閲覧するためのリンクをクリックすることができます。