著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。

序章

Linuxコンテナは、システムの他の部分から分離された一連のプロセスです。 エンドユーザーにとって、Linuxコンテナーは仮想マシンとして機能しますが、はるかに軽量です。 追加のLinuxカーネルを実行するオーバーヘッドはなく、コンテナーはCPUハードウェア仮想化のサポートを必要としません。 これは、同じサーバー上に仮想マシンよりも多くのコンテナーを作成できることを意味します。

顧客のために複数のWebサイトを実行する必要があるサーバーがあると想像してください。 一方では、各Webサイトは、ApacheまたはNginxWebサーバーの同じインスタンスの仮想ホスト/サーバーブロックである可能性があります。 一方、仮想マシンを使用する場合は、Webサイトごとに個別のネストされた仮想マシンを作成します。 Linuxコンテナーは、仮想ホストと仮想マシンの間のどこかにあります。

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

前提条件

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

  • Ubuntu20.04を実行しているサーバー。 ルート以外のsudoユーザーとファイアウォールを含むサーバーをセットアップするには、 Ubuntu 20.04を実行するDigitalOceanDropletを作成してから、初期サーバーセットアップガイドに従います。 サーバーのパブリックIPアドレスをメモします。 後でyour_server_ipと呼びます。

  • 少なくとも5GBのブロックストレージ。 これを設定するには、DigitalOceanのブロックストレージボリュームクイックスタートに従うことができます。 ブロックストレージの構成で、LXDが必要に応じて準備できるようにするには、Manually Format & Mountを選択します。 これを使用して、コンテナに関連するすべてのデータを保存します。

注: Ubuntu 20.04以降、LXDはスナップパッケージとして正式に利用可能になりました。 これは新しいパッケージ形式であり、いくつかの利点があります。 スナップパッケージは、スナップパッケージをサポートする任意のLinuxディストリビューションにインストールできます。 LXDスナップパッケージを実行するときは、少なくとも2GBのRAMを搭載したサーバーを使用することをお勧めします。 次の表は、LXDスナップパッケージの機能をまとめたものです。

特徴 スナップパッケージ
利用可能なLXDバージョン 2.0、3.0、4.0、4.x
メモリ要件 snapdサービスの場合は中程度。 2GBのRAMを搭載した推奨サーバー
アップグレードに関する考慮事項 LXDのアップグレードを最大60日延期できます
他のパッケージ形式からアップグレードする機能 debからsnapにアップグレードできます

このチュートリアルの残りの部分に従って、Ubuntu20.04のスナップパッケージのLXDを使用します。 ただし、LXD debパッケージを使用する場合は、チュートリアル Ubuntu18.04にLXDをインストールして使用する方法を参照してください。

ステップ1—LXD用の環境の準備

LXDを構成して実行する前に、サーバーの環境を準備します。 これには、sudoユーザーをlxdグループに追加し、ストレージバックエンドを構成することが含まれます。

root以外のアカウントをlxdUnixグループに追加する

root以外のアカウントを設定するときは、次のコマンドを使用して、それらをlxdグループに追加します。 adduserコマンドは、ユーザーアカウントを既存のUnixグループに追加するために、引数としてユーザーアカウントとUnixグループを取ります。

  1. sudo adduser sammy lxd

次に、新しいメンバーシップを適用します。

  1. su sammy

パスワードを入力し、ENTERを押します。

最後に、ユーザーがlxdグループに追加されたことを確認します。

  1. id -nG

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

  1. sammy sudo lxd

これで、LXDの構成を続行する準備が整いました。

ストレージバックエンドの準備

まず、ストレージバックエンドを構成します。

UbuntuでLXDを実行する場合に推奨されるストレージバックエンドは、ZFSファイルシステムです。 ZFSは、 DigitalOcean BlockStorageとも非常にうまく機能します。 LXDでZFSサポートを有効にするには、最初にパッケージリストを更新してから、zfsutils-linux補助パッケージをインストールします。

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

LXD初期化スクリプトを実行する準備がほぼ整いました。

その前に、ブロックストレージのデバイス名を特定してメモする必要があります。

これを行うには、lsを使用して/dev/disk/by-id/ディレクトリを確認します。

  1. ls -l /dev/disk/by-id/

この特定の例では、デバイス名のフルパスは/dev/disk/by-id/scsi-0DO_Volume_volume-fra1-0です。

Output
total 0 lrwxrwxrwx 1 root root 9 Sep 16 20:30 scsi-0DO_Volume_volume-fra1-0 -> ../../sda

ストレージデバイスの完全なファイルパスを書き留めます。 LXDを構成するときに、次の手順で使用します。

ステップ2—LXDの初期化と構成

LXDは、Ubuntu20.04でスナップパッケージとして利用できます。 プリインストールされていますが、設定する必要があります。

まず、LXDスナップパッケージがインストールされていることを確認します。 コマンドsnap listは、インストールされているスナップパッケージを表示します。

  1. snap list

Ubuntu20.04はLXD4.0.3をプレインストールし、4.0/stableチャネルを追跡しています。 LXD 4.0は5年間(2025年まで)サポートされます。 セキュリティアップデートのみを受信します。

Output of the "snap list" command — Listing the installed snap packages
Name Version Rev Tracking Publisher Notes core18 20200724 1885 latest/stable canonical✓ base lxd 4.0.3 16922 4.0/stable/… canonical✓ - snapd 2.45.3.1 8790 latest/stable canonical✓ snapd

LXDにインストールされているスナップパッケージの詳細については、snap info lxdを実行してください。 パッケージが最後に更新された日時を含め、利用可能なバージョンを確認できます。

次に、LXDを構成します。

LXDのストレージオプションの構成

sudo lxd initコマンドを使用してLXD初期化プロセスを開始します。

  1. sudo lxd init

まず、プログラムはLXDクラスタリングを有効にするかどうかを尋ねます。 このチュートリアルでは、ENTERを押してデフォルトのnoを受け入れるか、noと入力してからENTERを押します。 LXDクラスタリングは、LXDセットアップの高可用性を可能にする高度なトピックであり、クラスター内で少なくとも3台のLXDサーバーを実行する必要があります。

Output
Would you like to use LXD clustering? (yes/no) [default=no]: no

次の6つのプロンプトは、ストレージプールを処理します。 次の応答を返します。

  • ENTERを押して、新しいストレージプールを構成します。
  • ENTERを押して、デフォルトのストレージプール名を受け入れます。
  • ENTERを押して、デフォルトのzfsストレージバックエンドを受け入れます。
  • ENTERを押して、新しいZFSプールを作成します。
  • yesと入力して、既存のブロックデバイスを使用します。
  • 最後に、ブロックストレージデバイス名へのフルパスを入力します(これは前に記録したものです。 /dev/disk/by-id/device_name)のようになります。

あなたの答えは次のようになります:

Output
Do you want to configure a new storage pool? (yes/no) [default=yes]: yes Name of the new storage pool [default=default]: default Name of the storage backend to use (btrfs, dir, lvm, zfs) [default=zfs]: zfs Create a new ZFS pool? (yes/no) [default=yes]: yes 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

これで、LXDのストレージバックエンドが構成されました。 LXDのinitスクリプトを続行して、いくつかのネットワークオプションを構成します。

LXDのネットワークオプションの構成

LXDは、MAAS(Metal As A Server)サーバーに接続するかどうかを尋ねます。 MAASは、ベアメタルサーバーを仮想マシンのように見せ、仮想マシンのように処理するソフトウェアです。

LXDをスタンドアロンモードで実行しているため、デフォルトを受け入れてnoと答えます。

Output
Would you like to connect to a MAAS server? (yes/no) [default=no]: no

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

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

新しいローカルネットワークブリッジを作成するように求められたら、yesを選択します。

Output
Would you like to create a new local network bridge? (yes/no) [default=yes]: yes

次に、デフォルト名lxdbr0を受け入れます。

Output
What should the new bridge be called? [default=lxdbr0]: lxdbr0

ブリッジのプライベートIPアドレス範囲の自動選択を受け入れます。

Output
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto

最後に、LXDは次のその他の質問をします。

ネットワーク経由でLXDを管理するかどうかを尋ねられたら、ENTERを押すか、noと答えます。

Output
Would you like LXD to be available over the network? (yes/no) [default=no]: no

古いコンテナイメージを自動的に更新するかどうかを尋ねられたら、ENTERを押すか、yesと答えます。

Output
Would you like stale cached images to be updated automatically? (yes/no) [default=yes] yes

作成したYAML構成を表示して保持するかどうかを尋ねられたら、yesと答えます。 それ以外の場合は、ENTERを押すか、noと答えます。

Output
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: no

スクリプトはバックグラウンドで実行されます。 通常、出力を受信しません。

これで、LXDのネットワークとストレージのオプションが構成されました。 次に、最初のLXDコンテナを作成します。

ステップ2—LXDコンテナの作成と構成

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

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

  1. lxc list

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

Output of the "lxd list" command
To start your first container, try: lxc launch ubuntu:18.04 +------+-------+------+------+------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +------+-------+------+------+------+-----------+

次に、Nginxを実行するコンテナーを作成します。 これを行うには、最初にlxc launchコマンドを使用して、webserverという名前のUbuntu18.04コンテナーを作成して起動します。

webserverコンテナを作成します。 ubuntu:18.0418.04は、Ubuntu18.04のショートカットです。 ubuntu:は、LXDイメージの事前構成されたリポジトリーの識別子です。 画像名にubuntu:bionicを使用することもできます。

  1. lxc launch ubuntu:20.04 webserver

lxc image list ubuntu:を実行すると、使用可能なすべてのUbuntuイメージの完全なリストが表示され、lxc image list images:を実行すると他のLinuxディストリビューションが表示されます。 ubuntu:images:はどちらもコンテナイメージのリポジトリです。 コンテナイメージごとに、コマンドlxc image info ubuntu:20.04を使用して詳細情報を取得できます。

コンテナを作成するのはこれが初めてなので、このコマンドはインターネットからコンテナイメージをダウンロードしてキャッシュします。 新しいコンテナのダウンロードが完了すると、次の出力が表示されます。

Output
Creating webserver Starting webserver

webserverコンテナを起動したら、lxc listコマンドを使用してコンテナに関する情報を表示します。 namestateIPv4アドレスの列のみを表示するために、--columns ns4を追加しました。 デフォルトのlxc listコマンドには、さらに3つの列が表示されます。IPv6アドレス、コンテナーが永続的か一時的か、各コンテナーで使用可能なスナップショットがあるかどうかです。

  1. lxc list --columns ns4

出力には、各コンテナの名前、現在の状態、IPアドレス、およびタイプが記載されたテーブルが表示されます。

Output
+-----------+---------+------------------------------------+ | NAME | STATE | IPV4 | +-----------+---------+------------------------------------+ | webserver | RUNNING | your_webserver_container_ip (eth0) | +-----------+---------+------------------------------------+

LXDのDHCPサーバーはこのIPアドレスを提供し、ほとんどの場合、サーバーが再起動されても同じままです。 ただし、次の手順では、インターネットからコンテナに接続を転送するためのiptablesルールを作成します。 したがって、LXDのDHCPサーバーに、常に同じIPアドレスをコンテナーに与えるように指示する必要があります。

次の一連のコマンドは、静的IP割り当てを取得するようにコンテナーを構成します。 まず、デフォルトのLXDプロファイルから継承されたeth0デバイスのネットワーク構成を上書きします。 これにより、静的IPアドレスを設定できるため、コンテナに出入りするWebトラフィックの適切な通信が保証されます。

具体的には、lxc config deviceは、configアクションを実行してdeviceを構成するコマンドです。 最初の行には、コンテナwebserverからデバイスeth0をオーバーライドするサブアクションoverrideがあります。 2行目には、webserverコンテナのeth0デバイスのipv4.addressフィールドを、最初にDHCPサーバーによって指定されたIPアドレスに設定するサブアクションがあります。 。

最初のconfigコマンドを実行します。

  1. lxc config device override webserver eth0

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

Output
Device eth0 overridden for webserver

次に、静的IPを設定します。

  1. lxc config device set webserver eth0 ipv4.address your_webserver_container_ip

コマンドが成功した場合、出力はありません。

コンテナを再起動します。

  1. lxc restart webserver

次に、コンテナのステータスを確認します。

  1. lxc list

コンテナがRUNNINGであり、IPV4アドレスが静的アドレスであることがわかります。

これで、コンテナー内にNginxをインストールして構成する準備が整いました。

ステップ3—LXDコンテナ内でのNginxの構成

このステップでは、webserverコンテナーに接続し、Webサーバーを構成します。

lxc shellコマンドを使用してコンテナーに接続します。このコマンドは、コンテナーの名前を取得し、コンテナー内でシェルを開始します。

  1. lxc shell webserver

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

  1. [environment second]

このシェルは、ルートシェルであっても、コンテナに限定されます。 このシェルで実行するものはすべてコンテナーに残り、ホストサーバーにエスケープできません。

注:シェルをコンテナーに入れると、mesg: ttyname failed: No such deviceなどの警告が表示される場合があります。 このメッセージは、コンテナ内のシェルが構成ファイル/root/.profileからコマンドmesgを実行しようとしたときに生成されます。 あなたはそれを安全に無視することができます。 表示されないようにするには、コマンドmesg n || true/root/.profileから削除します。

コンテナに入ったら、パッケージリストを更新してNginxをインストールします。

  1. apt update
  2. apt install nginx

Nginxをインストールしたら、デフォルトのNginxWebページを編集します。 具体的には、このサイトがwebserverコンテナ内でホストされていることが明確になるように、2行のテキストを追加します。

nanoまたはお好みのエディターを使用して、ファイル/var/www/html/index.nginx-debian.htmlを開きます。

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

ハイライトされた2つのフレーズをファイルに追加します。

/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サーバーが機能していることをテストします。 これを行うには、前にlxc listコマンドを使用して見つけたWebコンテナのIPアドレスが必要です。

curlを使用して、Webサーバーをテストします。

  1. curl http://your_webserver_container_ip

NginxのデフォルトのHTMLウェルカムページが出力として表示されます。 編集内容が含まれていることに注意してください。

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サイトにアクセスできるようにします。

ステップ4—LXDを使用して着信接続をNginxコンテナに転送する

Nginxを構成したので、Webサーバーコンテナーをインターネットに接続します。 まず、サーバーがポート80で受信する可能性のある接続をwebserverコンテナーに転送するようにサーバーを設定する必要があります。 これを行うには、iptablesルールを作成してネットワーク接続を転送します。 IPTablesの詳細については、チュートリアルIPtablesFirewallの仕組みおよびIPtablesEssentials:一般的なファイアウォールルールとコマンドを参照してください。

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

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

  1. PORT=80 PUBLIC_IP=your_server_ip CONTAINER_IP=your_container_ip IFACE=eth0 sudo -E bash -c 'iptables -t nat -I PREROUTING -i $IFACE -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 $IFACEは、インターフェイスeth0を指定します。これは、Dropletsのホスト上のデフォルトのパブリックネットワークインターフェイスです。
  • -p TCPは、TCPプロトコルを使用していることを示しています。
  • -d $PUBLIC_IPは、ルールの宛先IPアドレスを指定します。
  • --dport $PORT:宛先ポート(80など)を指定します。
  • -j DNATは、宛先NAT(DNAT)へのジャンプを実行することを示しています。
  • --to-destination $CONTAINER_IP:$PORTは、リクエストを特定のコンテナのIPアドレスと宛先ポートに送信することを示しています。

注:このコマンドを再利用して、転送ルールを設定できます。 行の先頭で変数PORTPUBLIC_IPCONTAINER_IP、およびIFACEをリセットします。 ハイライトされた値を変更するだけです。

次に、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
...

次に、インターネットからWebサーバーにアクセスできることをテストします。

ローカルマシンからcurlコマンドを使用して、接続をテストします。

  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 install iptables-persistent

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

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

LXDが正常に構成されました。 最後のステップでは、サービスを停止して破棄する方法を学習します。

ステップ5—LXDを使用したコンテナーの停止と削除

コンテナを削除して削除することを決定できます。 このステップでは、コンテナを停止して削除します。

まず、コンテナを停止します。

  1. lxc stop webserver

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

  1. lxc list

コンテナの状態がSTOPPEDであることがわかります。

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

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

  1. lxc delete webserver

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

  1. lxc list

コマンドは以下を出力します:

+------+-------+------+------+------+-----------+
| 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

削除を確実にするために、ルールを再度リストします。

  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をインストールして構成しました。 次に、LXDコンテナ内で実行されているNginxを使用してWebサイトを作成し、IPtablesで公開しました。

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

LXDの使用方法の詳細については、LXDリファレンスドキュメントを参照してください。

LXDで練習するには、オンラインでLXDを試して、Webベースのチュートリアルに従ってください。

LXDのユーザーサポートを利用するには、LXDディスカッションフォーラムにアクセスしてください。