Linuxネットワーキング名前空間を使用して小規模プロジェクトを構築しようとしていますが、利用可能なすべてのLinuxネットワーキング機能とコンテナ化技術にわずかに圧倒され、この問題を正しい方法で進めているかどうかはわかりません。
質問/プロジェクト
eth0
私は現在、12個の静的パブリックIPv4アドレス(、、、、1.1.1.1
... 、)が割り当てられているネットワークデバイス()を持つ単純なLinuxボックスを持っています。私は複数の(ネットワーク)名前空間がある状況を作りたいと思います。各名前空間には、実際には独自の単一の名前空間があります。1.1.1.2
1.1.1.3
1.1.1.12
排他的パブリックIPv4アドレス/インターフェイス。
私の目標は、複数のシェルを回転させることです。それぞれは、独自のネットワーク名前空間によって分離されています。(pid、ipc...名前空間もあります)。例えば、7番シェルは、ns7
静的IPを持つ単一(仮想)イーサネットインターフェイスを持つネットワークネームスペースを使用します1.1.1.7
。たとえば、そのシェルでapache / nginxを起動して*:80でリッスンすると、1.1.1.7:80
他のIPv4アドレスのポート80に転送されるトラフィックはns7
再度到着しません。 80人も1.1.1.7
到着する必要があります。ただ名前空間のプロセスに到達しますns7
。
基本的なアイデアは、名前空間が実際に永続的であるということです。名前空間自体と関連する仮想ネットワークデバイスは、システムの起動時に(再)生成されて起動されます。
潜在的な解決策(私は正しい道を進んでいますか?)
私が直接実験せずに総合することができたので、解決策は以下に説明するものと似ているはずです。私はここで正しい道を行っていますか?
(仮想)レイヤ2ブリッジデバイスを作成して起動します
br0
。 L2(L3以外)で動作していることを確認してください。現在のイーサネットデバイス
eth0
設定を変更して、起動時に表示され続けますが、もはやIPアドレスが設定された(静的またはDHCPではない)、ブリッジeth0
に割り当てられないようにします。br0
いくつかのネットワークネームスペース
ip netns add ns2
、、、ip netns add ns3
...、を作成しますip netns add ns12
。デフォルト/ルートネームスペースをns1
。仮想イーサネットインターフェイス
net2a
の複数のペアを作成します。〜、net2b
〜net3a
、net3b
〜net4a
、 ...。net4b
各ペアに対して、-versionをブリッジa
に接続し、その名前空間に-versionを割り当てます。br0
b
各名前空間内で、適切なIPv4アドレス情報をローカルのvethデバイス(vethなど)に割り当て、
net2b
デバイスを起動します。ns2
IPv4転送を有効にする必要があるかもしれません(?)(
/proc/sys/net/ipv4/ip_forward
)および/またはARPフィルタリングを有効にする(?)(/proc/sys/net/ipv4/conf/all/arp_filter
)。各ネームスペースには(私が知る限り)独自のファイアウォール構成があるので、各ネームスペース内でいくつかのiptables / nftablesシェルスクリプトを実行し、いくつかの合理的なデフォルト値を設定し、ローカルニーズに合わせて調整します。
これらの仮想Linuxネットワークデバイスに慣れている人にとって、これは(ほぼ)実現可能な計画のように聞こえますか?
追加の詳細(重要な場合)
オペレーティングシステム情報:私はパッシブファイアウォールの設定にのみ使用する
kernel 4.18
、systemd
およびを含むCentOS 8を実行しています(firewalldエントリではありません)。SELinux
nftables
背景:提供されているすべてのアドレス(例)、
1.1.1.1
インターフェイス名(例eth0
)など明らかに希望これはある程度プライバシー上の理由でフィクションですが、もっと重要なのは「各ネームスペースでシェルを実行する」と言う私の意図と同様に簡潔性/簡潔性のためです。実際の要件:これらのネームスペース環境で実行されるさまざまな種類のソフトウェアがあり、各ネームスペースには独自のタスクがあり、多くの場合、複数のサービスが含まれます。また、IPv4 アドレスを互いに完全に分離することをお勧めします。ターゲットプログラムはサーバー/デーモン(Apache httpdの例など)であり、バインドする必要があります。実際プライベートipv4またはunixsocketのポートにバインドし、ルートネームスペースのソフトウェアをリバースプロキシミドルウェアとして機能させるのではなく、パブリックインターフェイス/ポートです。
なぜドッカーではないのですか?(TL / DR)これはオプションですが、楽しみのために何かをカスタマイズしたいと思いました。 (長い長い言葉を話す)これらの名前空間環境はほとんどすべて個人用であり、その1つは私の個人用メールサーバーを実行し、もう1つは個人用の低レベルWebホスティング用です。サーバートラフィックサイト、いくつかのライブWeb開発作業のためのWebサーバー、いくつかの趣味の友人のための無料のミニVPSとして機能するために私自身のsshd + webstackを実行するペア、基本的に自動化されたプロセスを実行するものなど。私がやろうとしていることと、dockerなどの一般的なコンテナ化スタックが提供するものとの間に大きな重複があることを知っています。実際、私が説明しているシステムはすでにほとんどの作業を行っており、ほとんどPodmanを使用しています(docker Sameとほぼ同じです)。 )残りのほとんどは、共通ルートネームスペースで並列に実行されます。私はいくつかの理由でこれらのいくつかをきちんと細かく管理するのが好きです。私の方法。私が実際に使用するコンテナソフトウェアが提供する唯一のものはLinuxカーネル機能なので、あきらめる価値のあるプロジェクトだと思います。包装紙そして、それなしでこれらのことを行う方法を見つけてください。私もこの仕事を探求することの教育的価値を楽しんでいます。なぜなら、それは私が一般的にやっていることではないからです。
産業用コンピュータ:(単一)名前空間内のプロセスがIPを介して他の名前空間(デフォルトの名前空間でもない)と通信する必要がある重大な理由はありません。しかし、心が変わると(これまでの私の考えがほとんど正しいと仮定すると)、追加のL2ブリッジを設定してプロセスの一部を繰り返すことができると思いました。ワイズ- 各名前空間をペアで接続し、対応するプライベートスタイルの
192.168.x.x
IPv4アドレスを割り当てます。VPS/クラウド:これは物理マシンではなく、VPS/仮想サーバー/クラウドサーバーです。現在コンピュータに存在する唯一の/単一のネットワークデバイスです。これは
eth0
実際にはens3
CentOSのインストールが完了する直前に自動的に呼び出され実行されるため、すでにそれ自体が仮想デバイスです。lsmod
現在表示されてveth
ロードされvirtio_net
ています。私のホスティングプロバイダはQemuを使ってこのVPSを提供しているようです。これが重要かどうかはわかりません。私はそうすべきではないと思います。現在のようにインターフェイスを複製(またはそれ以上作成)し、インターフェイスにIPv4と名前空間を直接割り当てることができるかどうかを調べるのに時間を費やしたので、ens3
ブリッジデバイスとベスのペアは必要ありませんでした。この検索では実際には何も出ておらず、最終的にはハイパーバイザーレベルで設定を変更するホスティングプロバイダの誰かの助けなしには不可能だと判断しました。これは一般的に役に立ち、そのような作業に開いている可能性があると思いますが、これは私の解決策が将来の変更にあまり柔軟性がなくなる可能性があるため、可能であればこの問題を完全に制御できる場所で行うことをお勧めします。デバイス。IPv6:簡潔さのためにIPv6への言及は省略します。また、IPv6アドレスブロックがあり、同様の方法で使用する予定です。しかし、私の考えでは、最初にIPv4を動作させ、次にIPv6を有効にしてそこから進むのが最善だと思います。大きく異なるとは想像できません。
私の実装:実際に初めて作業を行った後は、すべてを実装する方法を完全に確信できませんでした。プロジェクトのネットワーク部分では、
network-setup.sh
すべてのネットワーク関連の必須事項(名前空間、ブリッジデバイス、vetデバイスなど)があるかどうかをテストするためのシェルスクリプトを作成し、不足しているエントリを再生成または設定します。それからそれに行きなさいシステム単位ファイルシェルスクリプトを実行して表示します。ユニットファイル要件に応じてnetwork-online.target
。それから別のシェルスクリプトそしてユニットファイル(起動)プロセス中に後で実行するには、unshare
またはシステムinit
- 問題のプロセスを実際に開始するバージョンです。しかし、誰かがより良いアイデアを持っているなら、聞きたいです。さまざまな名前空間の実装:
man unshare
私が感じた潜在的な問題の1つは、util-linux()が呼び出すという印象を受けたことです。ネットワークネームスペースman ip-netns
同じ用語の iproute2( ) とは意味が異なります。しかし、前者が後者の上位セット/拡張であるのか、それとも完全に異なる互換性のない実装であるのかはまだわかりません。実際にコンテナ関連の技術を読むと、このような質問が繰り返し出てくるようです。
答え1
veth-pairを使用した接続アプローチは機能しますが、より簡単な方法があります。
を使用してくださいmacvlan
。たとえば、次を参照してください。ここまたはここいくつかの詳細と議論。
これは、物理インターフェイス(あなたの場合eth0
)を親インターフェイス(または「マスターインターフェイス」)として使用し、同じ親インターフェイスを使用する他のデバイスに完全に透過的でネットワークネームスペースに移動できる仮想インターフェイスです。
その後、名前空間内のIPv4またはIPv6アドレスをインターフェイスに割り当てると、コンテナ専用の追加の物理ネットワークインターフェイスがあるかのように機能します。
コンテナが互いに通信したいかどうかによって味が異なります。詳しくはマニュアルをお読みください。
はい、ファイアウォールが必要な場合は、各ネームスペースでもそうする必要があります。
名前空間を使用するBTW、Docker、およびその他の仮想化方法もmacvlan
sを使用しているので、Apache、nginxなどを必要とする場合は、他のすべての操作(他のファイルシステム、ローカルDNS、ポート)を実行するDockerおよび/またはDocker Composeの使用を検討してください。 。マッピング)。