序章

Linuxコンテナは、名前空間や制御グループなどのLinuxカーネルセキュリティ機能を使用して、システムの他の部分から分離されたプロセスのグループです。 これは仮想マシンに似た構造ですが、はるかに軽量です。 追加のカーネルを実行したり、ハードウェアをシミュレートしたりするオーバーヘッドはありません。 これは、同じサーバー上に複数のコンテナーを簡単に作成できることを意味します。

たとえば、顧客のために複数のWebサイトを実行するサーバーがあるとします。 従来のインストールでは、各WebサイトはApacheまたはNginxWebサーバーの同じインスタンスの仮想ホストになります。 ただし、Linuxコンテナーを使用すると、各Webサイトを独自のコンテナーと独自のWebサーバーにセットアップできます。 Linuxコンテナーを使用すると、システムの他の部分に影響を与えることなく、アプリケーションとその依存関係をコンテナーにバンドルできます。

LXD を使用すると、これらのコンテナーを作成および管理できます。 LXDは、コンテナーのライフサイクル全体を管理するハイパーバイザーサービスを提供します。 このチュートリアルでは、LXDを構成し、それを使用してコンテナーでNginxを実行します。 次に、インターネットからWebサイトにアクセスできるようにするために、トラフィックをコンテナにルーティングします。

前提条件

このチュートリアルを完了するには、次のものが必要です。

  • チュートリアルUbuntu16.04を使用した初期サーバーセットアップに従って構成された1つのUbuntu16.04サーバー、sudo非rootユーザーとファイアウォール。
  • 必要に応じて、チュートリアル DigitalOceanブロックストレージ入門に従って、20GB以上のブロックストレージを追加します。 これを使用して、コンテナに関連するすべてのデータを保存できます。

ステップ1—LXDの構成

LXDはすでにUbuntuにインストールされていますが、サーバーで使用する前に適切に構成する必要があります。 コンテナーを管理するためにユーザーアカウントを設定してから、コンテナーを格納するストレージバックエンドのタイプを構成し、ネットワークを構成する必要があります。

root以外のユーザーアカウントを使用してサーバーにログインします。 次に、ユーザーをlxdグループに追加して、すべてのコンテナー管理タスクを実行できるようにします。

  1. sudo usermod --append --groups lxd sammy

サーバーからログアウトして再度ログインすると、新しいSSHセッションが新しいグループメンバーシップで更新されます。 ログインすると、LXDの構成を開始できます。

次に、ストレージバックエンドを構成します。 LXDに推奨されるストレージバックエンドはZFSファイルシステムであり、事前に割り当てられたファイルに保存されるか、 BlockStorageを使用して保存されます。 LXDでZFSサポートを使用するには、パッケージリストを更新し、zfsutils-linuxパッケージをインストールします。

  1. sudo apt-get update
  2. sudo apt-get install zfsutils-linux

これで、LXDを構成できます。 lxd initコマンドを使用してLXD初期化プロセスを開始します。

  1. sudo lxd init

ストレージバックエンドの詳細を指定するように求められます。 その構成が完了したら、コンテナーのネットワークを構成します。

まず、新しいストレージプールを構成するかどうかを尋ねられます。 yes.と答える必要があります。

Do you want to configure a new storage pool (yes/no) [default=yes]? yes

次に、ストレージバックエンドの入力を求められ、dirまたはzfsの2つの選択肢が表示されます。 dirオプションは、サーバーのファイルシステム上のディレクトリにコンテナーを格納するようにLXDに指示します。 zfsオプションは、ZFS結合ファイルシステムと論理ボリュームマネージャーを使用します。

zfsオプションを使用します。 zfsを使用することで、ストレージ効率と応答性の両方が向上します。 たとえば、同じ初期コンテナイメージから10個のコンテナを作成する場合、それらはすべて1つのコンテナイメージのディスクスペースを使用します。 それ以降、最初のコンテナイメージへの変更のみがストレージバックエンドに保存されます。

Output
Name of the storage backend to use (dir or zfs) [default=zfs]: zfs

zfsを選択すると、新しいZFSプールを作成し、プールに名前を付けるように求められます。 yesを選択してプールを作成し、プールをlxdと呼びます。

Output
Create a new ZFS pool (yes/no) [default=yes]? yes Name of the new ZFS pool [default=lxd]: lxd

次に、既存のブロックデバイスを使用するかどうかを尋ねられます。

Output
Would you like to use an existing block device (yes/no) [default=no]?

yesと言う場合は、そのデバイスの場所をLXDに指示する必要があります。 noと言うと、LXDは事前に割り当てられたファイルを使用します。 このオプションを使用すると、サーバー自体の空き領域を使用します。

事前に割り当てられたファイルを使用するか、ブロックデバイスを使用するかに応じて、次の2つのセクションがあります。 ケースに適した手順に従ってください。 ストレージメカニズムを指定したら、コンテナのネットワークオプションを構成します。

オプション1-事前に割り当てられたファイルを使用する

コンテナを保存するための別のブロックストレージデバイスにアクセスできない場合は、事前に割り当てられたファイルを使用します。 次の手順に従って、事前に割り当てられたファイルを使用してコンテナーを保管するようにLXDを構成します。

まず、既存のブロックデバイスを使用するように求められたら、noと入力します。

Output
Would you like to use an existing block device (yes/no) [default=no]? no

次に、ループデバイスのサイズを指定するように求められます。これは、LXDが事前に割り当てられたファイルと呼ぶものです。 事前に割り当てられたファイルの推奨デフォルトサイズを使用します。

Output
Size in GB of the new loop device (1GB minimum) [default=15]: 15

経験則として、15GBは実際に作成する必要のある最小サイズです。 コンテナーを作成した後、少なくとも10GBの空きスペースが残るように、十分なスペースを事前に割り当てたいと考えています。

デバイスを構成すると、ネットワーク設定を構成するように求められます。 ステップ2に進み、セットアップを続行します。

オプション2–ブロックデバイスの使用

ブロックストレージをストレージバックエンドとして使用する場合は、LXDの構成で指定するために、作成したブロックストレージボリュームを指すデバイスを見つける必要があります。 DigitalOceanコントロールパネルボリュームタブに移動し、ボリュームを見つけて、その他ポップアップをクリックし、構成手順をクリックします。

ボリュームをフォーマットするコマンドを見て、デバイスを見つけます。 具体的には、sudo mkfs.ext4 -Fコマンドで指定されたパスを探します。 LXDに付ける正しいデバイス名を見つける必要があるだけなので、そのページからコマンドを実行しないでください。 次の図は、ボリュームのデバイス名の例を示しています。 赤い線で下線が引かれている部分だけが必要です。

The config instructions show the device for the created block Storage volume.

次のコマンドを使用してデバイス名を識別することもできます。

  1. ls -l /dev/disk/by-id/
  2. total 0
  3. lrwxrwxrwx 1 root root 9 Sep 16 20:30 scsi-0DO_Volume_volume-fra1-01 -> ../../sda

この場合、ボリュームのデバイス名は/dev/disk/by-id/scsi-0D0_Volume_volume-fra1-01ですが、実際の名前は異なる場合があります。

ボリュームのデバイス名を特定したら、LXDのインストールを続行します。 既存のブロックデバイスの使用についてプロンプトが表示されたら、yesを選択し、デバイスへのパスを指定します。

Output of the "lxd init" command
Would you like to use an existing block device (yes/no) [default=no]? yes Path to the existing block device: /dev/disk/by-id/scsi-0DO_Volume_volume-fra1-01

ディスクを指定すると、ネットワークオプションを構成するように求められます。

ステップ2—ネットワークの構成

ストレージバックエンドを構成すると、LXDのネットワークを構成するように求められます。

まず、LXDは、ネットワーク経由でアクセスできるようにするかどうかを尋ねます。 yesを選択すると、このサーバーにSSHで接続しなくても、ローカルコンピューターからLXDを管理できます。 noのデフォルト値を維持します。

Output of the "lxd init" command — LXD over the network
Would you like LXD to be available over the network (yes/no) [default=no]? no

このオプションを有効にする場合は、 LXD 2.0:リモートホストとコンテナーの移行を読んで詳細を確認してください。

次に、LXDコンテナのネットワークブリッジを構成するように求められます。 これにより、次の機能が有効になります。

  • 各コンテナは自動的にプライベートIPアドレスを取得します。
  • コンテナは、プライベートネットワークを介して相互に通信できます。
  • 各コンテナはインターネットへの接続を開始できます。
  • 作成したコンテナには、インターネットからアクセスできません。 明示的に有効にしない限り、インターネットから接続してコンテナに到達することはできません。 次のステップで、特定のコンテナへのアクセスを許可する方法を学習します。

LXDブリッジを構成するように求められたら、yesを選択します。

Output of the "lxd init" command — Networking for the containers
Do you want to configure the LXD bridge (yes/no) [default=yes]? yes

次に、次のダイアログが表示されます。

LXD networking configuration, start of configuration wizard

ネットワークブリッジを設定することを確認します。

橋に名前を付けるように求められます。 デフォルト値を受け入れます。

IPv4とIPv6の両方のネットワーク構成を実行するように求められます。 このチュートリアルでは、IPv4のみを使用します。

IPv4サブネットの設定を求められたら、はいを選択します。 ランダムなサブネットが構成されたことが通知されます。 OKを選択して続行します。

有効なIPv4アドレスの入力を求められたら、デフォルト値を受け入れます。

有効なCIDRマスクの入力を求められたら、デフォルト値を受け入れます。

最初のDHCPアドレスの入力を求められたら、デフォルト値を受け入れます。 最後のDHCPアドレス、およびDHCPクライアントの最大数についても同じようにします。

IPv4トラフィックをNATするように求められたら、はいを選択します。

IPv6サブネットを構成するように求められたら、いいえを選択します。 ネットワークのセットアップが完了すると、次の出力が表示されます。

Output
Warning: Stopping lxd.service, but it can still be activated by: lxd.socket LXD has been successfully configured.

これで、コンテナを作成する準備が整いました。

ステップ3—Nginxコンテナを作成する

これでLXDが正常に構成され、最初のコンテナーを作成および管理する準備が整いました。 lxcコマンドでコンテナを管理します。

lxc listを使用して、使用可能なインストール済みコンテナーを表示します。

  1. lxc list

次の出力が表示されます。

Output of the "lxd list" command
Generating a client certificate. This may take a minute... If this is your first time using LXD, you should also run: sudo lxd init To start your first container, try: lxc launch ubuntu:16.04 +------+-------+------+------+------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +------+-------+------+------+------+-----------+

lxcコマンドがLXDハイパーバイザーと通信するのはこれが初めてであるため、出力は、コマンドがLXDとの安全な通信のためにクライアント証明書を自動的に作成したことを示します。 次に、コンテナを起動する方法に関する情報を示します。 最後に、コマンドはコンテナの空のリストを表示します。これは、まだ作成していないために予想されます。

Nginxを実行するコンテナを作成しましょう。 そのためには、lxc launchコマンドを使用して、webserverという名前のUbuntu16.04コンテナーを作成して起動します。

webserverコンテナを作成します。

  1. lxc launch ubuntu:x webserver

ubuntu:xxは、Ubuntu16.04のコードネームであるXenialの最初の文字のショートカットです。 ubuntu:は、LXDイメージの事前構成されたリポジトリーの識別子です。 画像名にubuntu:16.04を使用することもできます。

lxc image list ubuntu:を実行すると、使用可能なすべてのUbuntuイメージの完全なリストが表示され、lxc image list images:を実行すると他のディストリビューションが表示されます。

コンテナを作成するのはこれが初めてなので、このコマンドはインターネットからコンテナイメージをダウンロードしてローカルにキャッシュし、新しいコンテナを作成する場合に、より迅速に作成できるようにします。 新しいコンテナが作成されると、次の出力が表示されます。

Output
Generating a client certificate. This may take a minute... If this is your first time using LXD, you should also run: sudo lxd init To start your first container, try: lxc launch ubuntu:16.04 Creating webserver Retrieving image: 100% Starting webserver

コンテナが実行されているので、lxc listコマンドを使用してコンテナに関する情報を表示します。

  1. lxc list

出力には、各コンテナーの名前、現在の状態、IPアドレス、タイプ、およびスナップショットが作成されているかどうかを示すテーブルが表示されます。

出力
+-----------+---------+-----------------------+------+------------+-----------+
|  NAME     |  STATE  |         IPV4          | IPV6 |    TYPE    | SNAPSHOTS |
+-----------+---------+-----------------------+------+------------+-----------+
| webserver | RUNNING | 10.10.10.100 (eth0)   |      | PERSISTENT | 0         |
+-----------+---------+-----------------------+------+------------+-----------+

注: LXDでIPv6を有効にした場合、lxc listコマンドの出力が画面に対して広すぎる可能性があります。 代わりにlxc list --columns ns4tSを使用できます。これは、名前、状態、IPv4、タイプ、および使用可能なスナップショットがあるかどうかのみを表示します。

コンテナのIPv4アドレスをメモします。 外界からのトラフィックを許可するようにファイアウォールを構成するために必要になります。

次に、コンテナ内にNginxを設定しましょう。

ステップ4—Nginxコンテナを構成する

webserverコンテナーに接続して、Webサーバーを構成しましょう。

lxc execコマンドを使用してコンテナーに接続します。このコマンドは、コンテナーの名前と実行するコマンドを取得します。

  1. lxc exec webserver -- sudo --login --user ubuntu

最初の--文字列は、lxcのコマンドパラメータがそこで停止し、残りの行がコンテナ内で実行されるコマンドとして渡されることを示します。 コマンドはsudo --login --user ubuntuで、コンテナー内の事前構成されたアカウントubuntuのログインシェルを提供します。

注: root としてコンテナーに接続する必要がある場合は、代わりにコマンドlxc exec webserver -- /bin/bashを使用してください。

コンテナ内に入ると、シェルプロンプトは次のようになります。

Output
ubuntu@webserver:~$

コンテナ内のこのubuntuユーザーには、sudoアクセスが事前設定されており、パスワードを指定せずにsudoコマンドを実行できます。 このシェルは、コンテナの範囲に限定されています。 このシェルで実行するものはすべてコンテナーに残り、ホストサーバーにエスケープできません。

このコンテナにNginxを設定しましょう。 コンテナ内のUbuntuインスタンスのパッケージリストを更新し、Nginxをインストールします。

  1. sudo apt-get update
  2. sudo apt-get install nginx

次に、このサイトのデフォルトのWebページを編集し、このサイトがwebserverコンテナーでホストされていることを明確にするテキストを追加します。 ファイル/var/www/html/index.nginx-debian.htmlを開きます。

  1. sudo nano /var/www/html/index.nginx-debian.html

ファイルに次の変更を加えます。

編集されたファイル/var/www/html/index.nginx-debian.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx on LXD container webserver!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx on LXD container webserver!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
...

ファイルを2か所で編集し、特にon LXD container webserverというテキストを追加しました。 ファイルを保存して、エディターを終了します。

次に、コンテナからログアウトして、ホストサーバーに戻ります。

  1. logout

curlを使用して、コンテナー内のWebサーバーが機能していることをテストします。 以前にlxd listコマンドを使用して見つけたWebコンテナのIPアドレスが必要になります。

  1. curl http://10.10.10.100/

出力は次のようになります。

Output
<!DOCTYPE html> <html> <head> <title>Welcome to nginx on LXD container webserver!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx on LXD container webserver!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> ...

Webサーバーは機能していますが、プライベートIPを介してのみアクセスできます。 世界中が私たちのWebサイトにアクセスできるように、外部リクエストをこのコンテナにルーティングしましょう。

ステップ5—着信接続をNginxコンテナに転送する

パズルの最後のピースは、Webサーバーコンテナをインターネットに接続することです。 Nginxはコンテナにインストールされ、デフォルトではインターネットからアクセスできません。 インターネットからポート80で受信する可能性のある接続をwebserverコンテナに転送するようにサーバーを設定する必要があります。 これを行うには、接続を転送するiptablesルールを作成します。 IPTablesの詳細については、IPtablesファイアウォールの仕組みおよびIPtablesEssentials:一般的なファイアウォールルールとコマンドを参照してください。

iptablesコマンドには、サーバーのパブリックIPアドレス(your_server_ip)とnginxコンテナーのプライベートIPアドレス(your_webserver_container_ip)の2つのIPアドレスが必要です。 、lxc listコマンドで取得できます。

次のコマンドを実行して、ルールを作成します。

  1. PORT=80 PUBLIC_IP=your_server_ip CONTAINER_IP=your_container_ip \
  2. sudo -E bash -c 'iptables -t nat -I PREROUTING -i eth0 -p TCP -d $PUBLIC_IP --dport $PORT -j DNAT --to-destination $CONTAINER_IP:$PORT -m comment --comment "forward to the Nginx container"'

コマンドの内訳は次のとおりです。

  • -t natは、アドレス変換にnatテーブルを使用していることを示します。
  • -I PREROUTINGは、ルールをPREROUTINGチェーンに追加することを指定します。
  • -i eth0は、ドロップレットのデフォルトのパブリックインターフェイスであるインターフェイスeth0を指定します。
  • -p TCPは、TCPプロトコルを使用していることを示しています。
  • -d $PUBLIC_IPは、ルールの宛先IPアドレスを指定します。
  • --dport $PORT:宛先ポート(80など)を指定します。
  • -j DNATは、宛先NAT(DNAT)へのジャンプを実行することを示しています。
  • --to-destination $CONTAINER_IP:$PORTは、リクエストを特定のコンテナのIPアドレスと宛先ポートに送信することを示しています。

注:このコマンドを再利用すると、行の先頭に変数PORTPUBLIC_IPCONTAINER_IPを設定するだけで、転送ルールを設定できます。 ハイライトされた値を変更するだけです。

次のコマンドを実行して、IPTablesルールを一覧表示できます。

  1. sudo iptables -t nat -L PREROUTING

次のような出力が表示されます。

[secondary_label Output] 
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             your_server_ip       tcp dpt:http /* forward to this container */ to:your_container_ip:80
...

次に、次のようにcurlコマンドを使用して、ローカルコンピューターからWebサーバーにアクセスすることにより、インターネットからWebサーバーに実際にアクセスできることをテストします。

  1. curl --verbose 'http://your_server_ip'

ヘッダーの後に、コンテナで作成したWebページのコンテンツが表示されます。

Output
* Trying your_server_ip... * Connected to your_server_ip (your_server_ip) port 80 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.10.0 (Ubuntu) ... <!DOCTYPE html> <html> <head> <title>Welcome to nginx on LXD container webserver!</title> <style> body { ...

これにより、リクエストがコンテナに送信されることが確認されます。

最後に、再起動後に再適用されるようにファイアウォールルールを保存するには、iptables-persistentパッケージをインストールします。

  1. sudo apt-get install iptables-persistent

パッケージをインストールすると、現在のファイアウォールルールを保存するように求められます。 現在のすべてのルールを受け入れて保存します。

マシンを再起動すると、ファイアウォールルールが存在します。 さらに、LXDコンテナのNginxサービスが自動的に再起動します。

すべての設定が完了したので、それを破棄する方法を見てみましょう。

ステップ5—コンテナの停止と削除

コンテナを降ろして交換することもできます。 そのプロセスを見ていきましょう。

コンテナを停止するには、lxc stopを使用します。

  1. lxc stop webserver

lxc listコマンドを使用してステータスを確認します。

Output
+-----------+---------+------+------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +-----------+---------+------+------+------------+-----------+ | webserver | STOPPED | | | PERSISTENT | 0 | +-----------+---------+------+------+------------+-----------+

コンテナを削除するには、lxc deleteを使用します。

  1. lxc delete webserver

lxc listを再度実行すると、コンテナが実行されていないことがわかります。

Output
+------+-------+------+------+------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +------+-------+------+------+------+-----------+

lxc helpコマンドを使用して、追加のオプションを表示します。

トラフィックをコンテナにルーティングするファイアウォールルールを削除するには、最初にこのコマンドを使用してルールのリストでルールを見つけます。これにより、行番号が各ルールに関連付けられます。

  1. sudo iptables -t nat -L PREROUTING --line-numbers

次のように、行番号が前に付いたルールが表示されます。

Output
Chain PREROUTING (policy ACCEPT) num target prot opt source destination 1 DNAT tcp -- anywhere your_server_ip tcp dpt:http /* forward to the Nginx container */ to:your_container_ip

その行番号を使用して、ルールを削除します。

  1. sudo iptables -t nat -D PREROUTING 1

ルールを再度リストして、ルールがなくなったことを確認します。

`sudo iptables -t nat -L PREROUTING --line-numbers`

ルールはなくなります:

Output
Chain PREROUTING (policy ACCEPT) num target prot opt source destination

サーバーを再起動したときにルールが戻らないように、変更を保存します。

  1. sudo netfilter-persistent save

これで、独自の設定で別のコンテナを起動し、トラフィックを転送するための新しいファイアウォールルールを追加できます。

結論

LXDコンテナで実行されているNginxを使用してWebサイトをセットアップしました。 ここから、それぞれが独自のコンテナに限定されたより多くのWebサイトを構成し、リバースプロキシを使用してトラフィックを適切なコンテナに転送できます。 チュートリアルUbuntu16.04でLXDを使用してNginxとHAProxyで複数のWebサイトをホストする方法では、その設定について説明します。

LXDでは、コンテナーの完全な状態のスナップショットを作成することもできます。これにより、バックアップを作成し、後でコンテナーをロールバックすることが容易になります。 また、LXDを2つの異なるサーバーにインストールすると、それらを接続して、インターネットを介してサーバー間でコンテナーを移行することができます。

LXDの詳細については、LXDの保守者によって作成されたLXD2.0に関するこの一連のブログ投稿を参照してください。

オンラインでLXDを試して、Webベースのチュートリアルに従ってさらに練習することもできます。