内容は次のとおりです。序文+環境+特定の操作+原則
0x0序文
Dockerとの最初の連絡後、突然「GUIプログラムを実行できるか」という考えが浮かんだので、急いでSTFW && RTFMを実行し、いくつかの関連ドキュメントを調べた後、ローカルでコンテナーのGUIテストプログラムを実行しました関連する作業と原則を記録します。
0x1関連環境
Docker version 18.09.2
XQuartz 2.7.11(xorg-server 1.18.4)
上記のソフトウェアは自作でインストールできます
0x2固有の操作
- XQuartz->設定->セキュリティ->「ネットワーククライアントからの接続を許可する」にチェックを入れます->プログラムを終了します。
- ターミナルに入力して
xhost +
(2つの間のスペースに注意)、XQuartzを再起動します。 - このように使用
nmap
占有されていない場合には会ったことがないので、私は:-Pを行う方法がわからないので...その後、次のステップに続けることができ、使用中にすでにあれば6000でのツールは、ポートが占有されている場合はX11サービスを表示するには、 - runまたはexecコンテナーに
-e DISPLAY=host.docker.internal:0
パラメーターを追加します。たとえば、xarclockクロックアプレットが既にインストールされている既存のコンテナーでtoyOSを実行するdocker exec -ite DISPLAY=host.docker.internal:0 toyOS /usr/bin/xarclock
と、小さなクロックGUIプログラムがローカルに表示されます。
0x3関連の原則
Linuxシステムおよび一部のUnixライクなシステムには、Xウィンドウシステム(以下、Xシステムと呼びます)の概念があります。XクライアントとしてのユーザーのGUIプログラムは、ローカルまたはリモートのXサーバーと対話して、Xを実行するための基本的なサポートを取得します。サーバーはデバイス上に画像を描画し、XQuartzはMacOSシステム用のXシステムです(私が理解しているレベルで)は、上記の機能サポートも提供します。
したがって、この原則を支持して、どのようにGUIプログラムドッカーを実行する問題を中に形質転換したX Serverがホストで実行されている方法およびXサーバーでXクライアントのホストドッカーを取得する方法と対話し、以下はこの問題を解決することでした2つの質問:
0x31ホストマシンでXサーバーを実行する方法
Xシステムの定義からわかるように、システム自体はネットワークベースのCSモデルをサポートできます(ただし、サービス側に重点が置かれています)。XQuartzの実装はもちろん例外ではありません。ただし、セキュリティ上の理由から、XQuartzはデフォルトでネットワーク経由の対話を許可していません。この制限を閉じるように、達成されるべき二つの側面が対応する、ある特定の操作 2つの1,2-操作、閉じたネットワーク接続の制限として文字通りの意味としての動作、第2動作が閉じられます実行して、接続識別(アクセス制御)、man xhost
詳細はそのマニュアルページを表示します。この実験の操作はローカルで実装されているため、接続認証は完全にオフになっていることに注意してください。これは、リモート操作に関しては非常に安全ではありません。
上記の手順が実行され、ポート6000が監視されている場合(デフォルト)、ホストマシンでXサーバーが正常に実行されました。次に、3番目の問題が解決されます。
0x32 DockerのXクライアントをホストのXサーバーと対話させる方法
Xクライアントのプログラムとして、Xサーバーと対話したい場合、おおまかに2つの方法があります。
- コマンドの後に
--display
関連する位置を示すパラメータ - ユーザーが事前
DISPLAY
に環境変数を設定し、プログラムが変数から関連情報を取得する
ここでは、あなたがしてコンテナを起動するときに、第二の方法を使用する-e
ために設定したパラメータDISPLAY
変数、今の問題は、変数の値がどのように解釈するかであるhost.docker.internal:0
ことを?
この変数のコロンの前の部分については、公式のDockerドキュメントに次の説明があります。
ホストのIPアドレスが変化している(ネットワークアクセスがない場合は変化しない)。18.03以降は
host.docker.internal
、ホストが使用する内部IPアドレスに解決される特別なDNS名に接続することをお勧めします。
言い換えれば、この値は、本質的に、内部IPホストを取得しているこれを確認するために、次のことができifconfig
、実際のIPホストコマンドを表示し、DISPLAY
値が置き換えられyour_ip:0
、見つけることができ、以前のように実行することができます。彼らは実際のIPを取得したいので、元を使用して、この実験は、最初のプロセスが非常に煩雑である理由、そして第二には、ネットワーク機器の状態にあるとされ、文書の記述にで見ることができる(or none if you have no network access)
、というこの文、このパラメータ設定は、ネットワーク状態がなくても正常に実行できます。
次いで、DISPLAY
値として解釈することができるyour_ip:0
この形式のために、実際に、その完全な形はyour_ip: display_number. screen_number
、この実験で実際に書き込まれhost.docker.internal:0.0
、display_number
そしてscreen_number
0からカウントされ、前者は、基準ストリーム(表示入力を含む入力ストリームを示し、非常に少数の人々は、複数の画面を使用しているため、特定のディスプレイへの入力ストリームを表し、キーボード、マウスなど)、ので、screen_number
ほとんどの場合、それは省略失われることが、0です。
X11プロトコルの公式文書、以下の説明では:display_number
TCP接続の場合、特定のホスト上のディスプレイには0から始まる番号が付けられており、ディスプレイNのサーバーはポート6000 + Nで接続をリッスンして受け入れます。
つまり、この値は実際にはホストマシン上のX11サービスが占有するポートに依存します。ポート番号から6000を減算します。これは、上記のコマンドのコロンの後の0の特定の意味です。これを確認するには、使用することができますsocat
実行するためのツールを socat tcp-listen:6100,reuseaddr,fork tcp:localhost:6000
コマンドを、6100メッセージがこのように、上記の説明に従って、ポート6000ポートに転送され、DISPLAY
可能な変数の値をhost.docker.internal:100
交換した後に完全なコマンドを実行するには、GUIのテストプログラムとして実行するように見つけることができます。