Ubuntu16.04でLXDをセットアップして使用する方法
序章
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
グループに追加して、すべてのコンテナー管理タスクを実行できるようにします。
- sudo usermod --append --groups lxd sammy
サーバーからログアウトして再度ログインすると、新しいSSHセッションが新しいグループメンバーシップで更新されます。 ログインすると、LXDの構成を開始できます。
次に、ストレージバックエンドを構成します。 LXDに推奨されるストレージバックエンドはZFSファイルシステムであり、事前に割り当てられたファイルに保存されるか、 BlockStorageを使用して保存されます。 LXDでZFSサポートを使用するには、パッケージリストを更新し、zfsutils-linux
パッケージをインストールします。
- sudo apt-get update
- sudo apt-get install zfsutils-linux
これで、LXDを構成できます。 lxd init
コマンドを使用してLXD初期化プロセスを開始します。
- 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つのコンテナイメージのディスクスペースを使用します。 それ以降、最初のコンテナイメージへの変更のみがストレージバックエンドに保存されます。
OutputName of the storage backend to use (dir or zfs) [default=zfs]: zfs
zfs
を選択すると、新しいZFSプールを作成し、プールに名前を付けるように求められます。 yes
を選択してプールを作成し、プールをlxd
と呼びます。
OutputCreate a new ZFS pool (yes/no) [default=yes]? yes
Name of the new ZFS pool [default=lxd]: lxd
次に、既存のブロックデバイスを使用するかどうかを尋ねられます。
OutputWould you like to use an existing block device (yes/no) [default=no]?
yes
と言う場合は、そのデバイスの場所をLXDに指示する必要があります。 no
と言うと、LXDは事前に割り当てられたファイルを使用します。 このオプションを使用すると、サーバー自体の空き領域を使用します。
事前に割り当てられたファイルを使用するか、ブロックデバイスを使用するかに応じて、次の2つのセクションがあります。 ケースに適した手順に従ってください。 ストレージメカニズムを指定したら、コンテナのネットワークオプションを構成します。
オプション1-事前に割り当てられたファイルを使用する
コンテナを保存するための別のブロックストレージデバイスにアクセスできない場合は、事前に割り当てられたファイルを使用します。 次の手順に従って、事前に割り当てられたファイルを使用してコンテナーを保管するようにLXDを構成します。
まず、既存のブロックデバイスを使用するように求められたら、no
と入力します。
OutputWould you like to use an existing block device (yes/no) [default=no]? no
次に、ループデバイスのサイズを指定するように求められます。これは、LXDが事前に割り当てられたファイルと呼ぶものです。 事前に割り当てられたファイルの推奨デフォルトサイズを使用します。
OutputSize in GB of the new loop device (1GB minimum) [default=15]: 15
経験則として、15GBは実際に作成する必要のある最小サイズです。 コンテナーを作成した後、少なくとも10GBの空きスペースが残るように、十分なスペースを事前に割り当てたいと考えています。
デバイスを構成すると、ネットワーク設定を構成するように求められます。 ステップ2に進み、セットアップを続行します。
オプション2–ブロックデバイスの使用
ブロックストレージをストレージバックエンドとして使用する場合は、LXDの構成で指定するために、作成したブロックストレージボリュームを指すデバイスを見つける必要があります。 DigitalOceanコントロールパネルのボリュームタブに移動し、ボリュームを見つけて、その他ポップアップをクリックし、構成手順をクリックします。 。
ボリュームをフォーマットするコマンドを見て、デバイスを見つけます。 具体的には、sudo mkfs.ext4 -F
コマンドで指定されたパスを探します。 LXDに付ける正しいデバイス名を見つける必要があるだけなので、そのページからコマンドを実行しないでください。 次の図は、ボリュームのデバイス名の例を示しています。 赤い線で下線が引かれている部分だけが必要です。
次のコマンドを使用してデバイス名を識別することもできます。
- ls -l /dev/disk/by-id/
- total 0
- 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" commandWould 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 networkWould 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 containersDo you want to configure the LXD bridge (yes/no) [default=yes]? yes
次に、次のダイアログが表示されます。
ネットワークブリッジを設定することを確認します。
橋に名前を付けるように求められます。 デフォルト値を受け入れます。
IPv4とIPv6の両方のネットワーク構成を実行するように求められます。 このチュートリアルでは、IPv4のみを使用します。
IPv4サブネットの設定を求められたら、はいを選択します。 ランダムなサブネットが構成されたことが通知されます。 OKを選択して続行します。
有効なIPv4アドレスの入力を求められたら、デフォルト値を受け入れます。
有効なCIDRマスクの入力を求められたら、デフォルト値を受け入れます。
最初のDHCPアドレスの入力を求められたら、デフォルト値を受け入れます。 最後のDHCPアドレス、およびDHCPクライアントの最大数についても同じようにします。
IPv4トラフィックをNATするように求められたら、はいを選択します。
IPv6サブネットを構成するように求められたら、いいえを選択します。 ネットワークのセットアップが完了すると、次の出力が表示されます。
OutputWarning: Stopping lxd.service, but it can still be activated by:
lxd.socket
LXD has been successfully configured.
これで、コンテナを作成する準備が整いました。
ステップ3—Nginxコンテナを作成する
これでLXDが正常に構成され、最初のコンテナーを作成および管理する準備が整いました。 lxc
コマンドでコンテナを管理します。
lxc list
を使用して、使用可能なインストール済みコンテナーを表示します。
- lxc list
次の出力が表示されます。
Output of the "lxd list" commandGenerating 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
コンテナを作成します。
- lxc launch ubuntu:x webserver
ubuntu:x
のx
は、Ubuntu16.04のコードネームであるXenialの最初の文字のショートカットです。 ubuntu:
は、LXDイメージの事前構成されたリポジトリーの識別子です。 画像名にubuntu:16.04
を使用することもできます。
注:lxc image list ubuntu:
を実行すると、使用可能なすべてのUbuntuイメージの完全なリストが表示され、lxc image list images:
を実行すると他のディストリビューションが表示されます。
コンテナを作成するのはこれが初めてなので、このコマンドはインターネットからコンテナイメージをダウンロードしてローカルにキャッシュし、新しいコンテナを作成する場合に、より迅速に作成できるようにします。 新しいコンテナが作成されると、次の出力が表示されます。
OutputGenerating 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
コマンドを使用してコンテナに関する情報を表示します。
- 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
コマンドを使用してコンテナーに接続します。このコマンドは、コンテナーの名前と実行するコマンドを取得します。
- lxc exec webserver -- sudo --login --user ubuntu
最初の--
文字列は、lxc
のコマンドパラメータがそこで停止し、残りの行がコンテナ内で実行されるコマンドとして渡されることを示します。 コマンドはsudo --login --user ubuntu
で、コンテナー内の事前構成されたアカウントubuntu
のログインシェルを提供します。
注: root としてコンテナーに接続する必要がある場合は、代わりにコマンドlxc exec webserver -- /bin/bash
を使用してください。
コンテナ内に入ると、シェルプロンプトは次のようになります。
Outputubuntu@webserver:~$
コンテナ内のこのubuntuユーザーには、sudo
アクセスが事前設定されており、パスワードを指定せずにsudo
コマンドを実行できます。 このシェルは、コンテナの範囲に限定されています。 このシェルで実行するものはすべてコンテナーに残り、ホストサーバーにエスケープできません。
このコンテナにNginxを設定しましょう。 コンテナ内のUbuntuインスタンスのパッケージリストを更新し、Nginxをインストールします。
- sudo apt-get update
- sudo apt-get install nginx
次に、このサイトのデフォルトのWebページを編集し、このサイトがwebserver
コンテナーでホストされていることを明確にするテキストを追加します。 ファイル/var/www/html/index.nginx-debian.html
を開きます。
- sudo nano /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
というテキストを追加しました。 ファイルを保存して、エディターを終了します。
次に、コンテナからログアウトして、ホストサーバーに戻ります。
- logout
curl
を使用して、コンテナー内のWebサーバーが機能していることをテストします。 以前にlxd list
コマンドを使用して見つけたWebコンテナのIPアドレスが必要になります。
- 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
コマンドで取得できます。
次のコマンドを実行して、ルールを作成します。
- PORT=80 PUBLIC_IP=your_server_ip CONTAINER_IP=your_container_ip \
- 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アドレスと宛先ポートに送信することを示しています。
注:このコマンドを再利用すると、行の先頭に変数PORT
、PUBLIC_IP
、CONTAINER_IP
を設定するだけで、転送ルールを設定できます。 ハイライトされた値を変更するだけです。
次のコマンドを実行して、IPTablesルールを一覧表示できます。
- 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サーバーに実際にアクセスできることをテストします。
- 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
パッケージをインストールします。
- sudo apt-get install iptables-persistent
パッケージをインストールすると、現在のファイアウォールルールを保存するように求められます。 現在のすべてのルールを受け入れて保存します。
マシンを再起動すると、ファイアウォールルールが存在します。 さらに、LXDコンテナのNginxサービスが自動的に再起動します。
すべての設定が完了したので、それを破棄する方法を見てみましょう。
ステップ5—コンテナの停止と削除
コンテナを降ろして交換することもできます。 そのプロセスを見ていきましょう。
コンテナを停止するには、lxc stop
を使用します。
- lxc stop webserver
lxc list
コマンドを使用してステータスを確認します。
Output+-----------+---------+------+------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-----------+---------+------+------+------------+-----------+
| webserver | STOPPED | | | PERSISTENT | 0 |
+-----------+---------+------+------+------------+-----------+
コンテナを削除するには、lxc delete
を使用します。
- lxc delete webserver
lxc list
を再度実行すると、コンテナが実行されていないことがわかります。
Output+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+
lxc help
コマンドを使用して、追加のオプションを表示します。
トラフィックをコンテナにルーティングするファイアウォールルールを削除するには、最初にこのコマンドを使用してルールのリストでルールを見つけます。これにより、行番号が各ルールに関連付けられます。
- sudo iptables -t nat -L PREROUTING --line-numbers
次のように、行番号が前に付いたルールが表示されます。
OutputChain 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
その行番号を使用して、ルールを削除します。
- sudo iptables -t nat -D PREROUTING 1
ルールを再度リストして、ルールがなくなったことを確認します。
`sudo iptables -t nat -L PREROUTING --line-numbers`
ルールはなくなります:
OutputChain PREROUTING (policy ACCEPT)
num target prot opt source destination
サーバーを再起動したときにルールが戻らないように、変更を保存します。
- sudo netfilter-persistent save
これで、独自の設定で別のコンテナを起動し、トラフィックを転送するための新しいファイアウォールルールを追加できます。
結論
LXDコンテナで実行されているNginxを使用してWebサイトをセットアップしました。 ここから、それぞれが独自のコンテナに限定されたより多くのWebサイトを構成し、リバースプロキシを使用してトラフィックを適切なコンテナに転送できます。 チュートリアルUbuntu16.04でLXDを使用してNginxとHAProxyで複数のWebサイトをホストする方法では、その設定について説明します。
LXDでは、コンテナーの完全な状態のスナップショットを作成することもできます。これにより、バックアップを作成し、後でコンテナーをロールバックすることが容易になります。 また、LXDを2つの異なるサーバーにインストールすると、それらを接続して、インターネットを介してサーバー間でコンテナーを移行することができます。
LXDの詳細については、LXDの保守者によって作成されたLXD2.0に関するこの一連のブログ投稿を参照してください。
オンラインでLXDを試して、Webベースのチュートリアルに従ってさらに練習することもできます。