序章

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

たとえば、サーバーがあり、クライアント用にWebサイトを含むいくつかのサービスを設定しているとします。 従来のインストールでは、各WebサイトはApacheまたはNginxWebサーバーの同じインスタンスの仮想ホストになります。 ただし、Linuxコンテナーでは、各Webサイトは独自のWebサーバーを備えた独自のコンテナーで構成されます。

LXD を使用して、これらのコンテナーを作成および管理できます。 LXDは、コンテナーのライフサイクル全体を管理するハイパーバイザーサービスを提供します。

このチュートリアルでは、LXDを使用して、同じサーバーに2つのNginxベースのWebサイトをインストールし、それぞれが独自のコンテナーに限定されます。 次に、リバースプロキシとして機能する3番目のコンテナにHAProxyをインストールします。 次に、インターネットから両方のWebサイトにアクセスできるようにするために、トラフィックをHAProxyコンテナにルーティングします。

前提条件

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

  • チュートリアルUbuntu16.04を使用した初期サーバーセットアップに従って構成された1つのUbuntu16.04サーバー、sudo非rootユーザーとファイアウォール。
  • 2つの完全修飾ドメイン名(FQDN)。各DNS AレコードはサーバーのIPアドレスを指しています。 これを構成するには、チュートリアルDigitalOceanを使用してホスト名を設定する方法に従ってください。
  • 必要に応じて、チュートリアル DigitalOceanブロックストレージ入門に従って、20GB以上のブロックストレージを追加します。 これを使用して、コンテナに関連するすべてのデータを保存できます。

ステップ1—ユーザーをに追加する lxd グループ

root以外のユーザーアカウントを使用してサーバーにログインします。 この非ユーザーアカウントを使用して、すべてのコンテナ管理タスクを実行します。 これを機能させるには、最初にこのユーザーをに追加する必要があります lxd グループ。 次のコマンドでこれを行います。

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

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

ステップ2—LXDの構成

LXDを使用するには、適切に構成する必要があります。 最も重要な構成の決定は、コンテナーを格納するためのストレージバックエンドのタイプです。 LXDに推奨されるストレージバックエンドはZFSファイルシステムであり、事前に割り当てられたファイルに保存されるか、 BlockStorageを使用して保存されます。 LXDでZFSサポートを使用するには、 zfsutils-linux パッケージ:

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

これをインストールすると、LXDを初期化する準備が整います。 初期化中に、ZFSストレージバックエンドの詳細を指定するように求められます。 事前に割り当てられたファイルを使用するか、ストレージをブロックするかによって、次の2つのセクションがあります。 ケースに適した手順に従ってください。 ストレージメカニズムを指定したら、コンテナのネットワークオプションを構成します。

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

以下の手順に従って、事前に割り当てられたファイルを使用してコンテナーを保管するようにLXDを構成します。 まず、次のコマンドを実行して、LXD初期化プロセスを開始します。

  1. sudo lxd init

次の出力に示すように、いくつかの情報を入力するように求められます。 ループデバイスと呼ばれる、事前に割り当てられたファイルの推奨サイズを含む、すべてのデフォルトを選択します。

Output
Name of the storage backend to use (dir or zfs) [default=zfs]: zfs Create a new ZFS pool (yes/no) [default=yes]? yes Name of the new ZFS pool [default=lxd]: lxd Would you like to use an existing block device (yes/no) [default=no]? no Size in GB of the new loop device (1GB minimum) [default=15]: 15 Would you like LXD to be available over the network (yes/no) [default=no]? no Do you want to configure the LXD bridge (yes/no) [default=yes]? yes Warning: Stopping lxd.service, but it can still be activated by: lxd.socket LXD has been successfully configured.

推奨サイズは、サーバーの使用可能なディスク容量から自動的に計算されます。

デバイスを構成したら、ネットワーク設定を構成します。これについては、次のオプションのセクションで説明します。

オプション2–ブロックストレージの使用

ブロックストレージを使用する場合は、LXDの構成で指定するために、作成したブロックストレージボリュームを指すデバイスを見つける必要があります。 DigitalOceanコントロールペインlのVolumesタブに移動し、ボリュームを見つけて、 More ポップアップをクリックし、Configをクリックします。指示

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

この場合、ボリューム名は /dev/disk/by-id/scsi-0D0_Volume_volume-fra1-01、あなたのものは異なるかもしれませんが。

ボリュームを特定したら、端末に戻り、次のコマンドを発行してLXD初期化プロセスを開始します。

  1. sudo lxd init

一連の質問が表示されます。 次の出力に示すように、質問に答えてください。

Output
Name of the storage backend to use (dir or zfs) [default=zfs]: zfs Create a new ZFS pool (yes/no) [default=yes]? yes Name of the new ZFS pool [default=lxd]: 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

次に、残りの質問にデフォルト値を使用します。

Output of the "lxd init" command
Would you like LXD to be available over the network (yes/no) [default=no]? no Do you want to configure the LXD bridge (yes/no) [default=yes]? yes Warning: Stopping lxd.service, but it can still be activated by: lxd.socket LXD has been successfully configured.

プロセスが完了したら、ネットワークを構成します。

ネットワーキングの構成

初期化プロセスでは、次の図のような一連の画面が表示されます。これらの画面では、コンテナのネットワークブリッジを構成して、コンテナがプライベートIPアドレスを取得し、相互に通信し、インターネットにアクセスできるようにします。

各オプションにはデフォルト値を使用しますが、IPv6ネットワーキングについて尋ねられた場合は、このチュートリアルでは使用しないため、いいえを選択します。

ネットワーク構成が完了すると、コンテナを作成する準備が整います。

ステップ3—コンテナの作成

LXDの構成に成功しました。 ストレージバックエンドの場所を指定し、新しく作成されたコンテナのデフォルトのネットワークを構成しました。 いくつかのコンテナを作成して管理する準備が整いました。 lxc 指図。

インストールされている利用可能なコンテナを一覧表示する最初のコマンドを試してみましょう。

  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との安全な通信のためにクライアント証明書を自動的に作成したことを通知します。 次に、コンテナを起動する方法に関する情報が表示されます。 最後に、コマンドはコンテナの空のリストを表示します。これは、まだ作成していないために予想されます。

3つのコンテナを作成しましょう。 Webサーバーごとに1つ作成し、リバースプロキシ用に3つ目のコンテナーを作成します。 リバースプロキシの目的は、インターネットからの着信接続をコンテナ内の正しいWebサーバーに転送することです。

を使用します lxc launch Ubuntu 16.04を作成して起動するコマンド(ubuntu:x)という名前のコンテナ web1. The xubuntu:x は、Ubuntu16.04のコードネームであるXenialの最初の文字のショートカットです。 ubuntu: LXDイメージの事前設定されたリポジトリの識別子です。

:実行すると、利用可能なすべてのUbuntuイメージの完全なリストを見つけることができます lxc image list ubuntu: および実行することによる他のディストリビューション lxc image list images:.

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

  1. lxc launch ubuntu:x web1
  2. lxc launch ubuntu:x web2
  3. lxc launch ubuntu:x haproxy

コンテナを作成するのはこれが初めてなので、最初のコマンドはインターネットからコンテナイメージをダウンロードし、ローカルにキャッシュします。 次の2つのコンテナは、大幅に高速に作成されます。

ここでは、コンテナの作成からのサンプル出力を見ることができます web1.

Output
Creating web1 Retrieving image: 100% Starting web1

空のバニラコンテナを3つ作成したので、 lxc list それらに関する情報を表示するコマンド:

  1. lxc list

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

出力
+---------+---------+-----------------------+------+------------+-----------+
|  NAME   |  STATE  |         IPV4          | IPV6 |    TYPE    | SNAPSHOTS |
+---------+---------+-----------------------+------+------------+-----------+
| haproxy | RUNNING | 10.10.10.10 (eth0)    |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
| web1    | RUNNING | 10.10.10.100 (eth0)   |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
| web2    | RUNNING | 10.10.10.200 (eth0)   |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+

コンテナ名とそれに対応するIPv4アドレスをメモします。 サービスを構成するためにそれらが必要になります。

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

に接続しましょう web1 コンテナを作成し、最初のWebサーバーを構成します。

接続するには、 lxc exec コマンド。コンテナの名前と実行するコマンドを受け取ります。 次のコマンドを実行して、コンテナに接続します。

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

The -- 文字列は、 lxc ここで停止する必要があり、残りの行はコンテナ内で実行されるコマンドとして渡されます。 コマンドは sudo --login --user ubuntu、事前設定されたアカウントのログインシェルを提供します ubuntu コンテナ内。

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

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

Output
ubuntu@web1:~$

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

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

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

このサイトのデフォルトのWebページを編集して、このサイトがでホストされていることを明確にするテキストを追加しましょう。 web1 容器。 ファイルを開く /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 web1!</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 web1!</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 web1. ファイルを保存して、エディターを終了します。

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

  1. logout

に対してこの手順を繰り返します web2 容器。 ログインしてNginxをインストールし、ファイルを編集します /var/www/html/index.nginx-debian.html 言及する web2. 次に、を終了します web2 容器。

使ってみよう curl コンテナ内のWebサーバーが機能していることをテストします。 前に示したWebコンテナのIPアドレスが必要です。

  1. curl http://10.10.10.100/

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

Output of "curl http://10.10.10.100/" command
<!DOCTYPE html> <html> <head> <title>Welcome to nginx on LXD container web1!</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 web1!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> ...

を使用して、2番目のコンテナもテストします curl コマンドとそのIPアドレスも正しく設定されていることを確認します。 両方のコンテナを設定したら、HAProxyの設定に進むことができます。

ステップ5—HAProxyコンテナを設定する

これらのコンテナの前にプロキシとしてHAProxyを設定します。 これがどのように機能するかについてさらに背景が必要な場合は、チュートリアルHAProxyと負荷分散の概念の概要を確認してください。 使用するドメイン名に基づいて、トラフィックを各コンテナに転送します。 ドメインを使用しますexample.com 次の構成例では、このチュートリアルのようなドキュメント用の特別予約ドメインです。 ホスト名で最初のウェブサイトを利用できるようにします example.comwww.example.com. 2番目のウェブサイトは www2.example.com. これらのドメイン名の代わりに独自のドメイン名を使用してください。

にログインします haproxy 容器:

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

インストールパッケージのリストを更新し、HAProxyをインストールします。

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

インストールが完了したら、HAProxyを設定できます。 HAProxyの設定ファイルは次の場所にあります。 /etc/haproxy/haproxy.cfg. お気に入りのテキストエディタでファイルを開きます。

  1. sudo nano /etc/haproxy/haproxy.cfg

まず、いくつかの変更を加えます defaults セクション。 追加します forwardfor オプションなので、Webクライアントの実際のソースIPを保持し、 http-server-close オプション。セッションの再利用と待ち時間の短縮を可能にします。

/etc/haproxy/haproxy.conf
global
...
defaults
	log	global
	mode	http
	option	httplog
	option	dontlognull
	option 	forwardfor
	option 	http-server-close
	timeout connect 5000
	timeout client  50000
	timeout server  50000
...

次に、2つのバックエンドコンテナを指すようにフロントエンドを構成します。 新しいを追加します frontend と呼ばれるセクション www_frontend これは次のようになります。

/etc/haproxy/haproxy.conf
frontend www_frontend
	bind *:80		# Bind to port 80 (www) on the container

	# It matches if the HTTP Host: field mentions any of the hostnames (after the '-i').
	acl host_web1 hdr(host) -i example.com www.example.com
	acl host_web2 hdr(host) -i web2.example.com

	# Redirect the connection to the proper server cluster, depending on the match.
	use_backend web1_cluster if host_web1
	use_backend web2_cluster if host_web2

The acl コマンドはWebサーバーのホスト名と一致し、対応するリクエストをリダイレクトします backend セクション。

次に、2つの新しい定義をします backend セクション(Webサーバーごとに1つ)、およびそれらに名前を付けます web1_clusterweb2_cluster それぞれ。 次のコードをファイルに追加して、バックエンドを定義します。

/etc/haproxy/haproxy.conf
backend web1_cluster
	balance leastconn
   	# We set the X-Client-IP HTTP header. This is useful if we want the web server to know the real client IP.
	http-request set-header X-Client-IP %[src]
	# This backend, named here "web1", directs to container "web1.lxd" (hostname).
	server web1 web1.lxd:80 check

backend web2_cluster
	balance leastconn
	http-request set-header X-Client-IP %[src]
	server web2 web2.lxd:80 check

The balance オプションは、負荷分散戦略を示します。 この場合、接続数を最小限に抑えます。 The http-request オプションは、実際のWebクライアントIPでHTTPヘッダーを設定します。 このヘッダーを設定しなかった場合、Webサーバーはすべての接続の送信元IPとしてHAProxy IPアドレスを記録するため、トラフィックの発信元を分析することがより困難になります。 The server オプションはサーバーの任意の名前を指定します(web1)、続いてサーバーのホスト名とポート…

LXDはコンテナ用のDNSサーバーを提供するため、 web1.lxd に関連付けられたIPに解決されます web1 容器。 他のコンテナには、次のような独自のホスト名があります。 web2.lxdhaproxy.lxd.

The check パラメータは、HAPRoxyにWebサーバーでヘルスチェックを実行して、それが利用可能であることを確認するように指示します。

構成が有効であることをテストするには、次のコマンドを実行します。

  1. /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c

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

出力
Configuration file is valid

新しい構成を読み取るようにHAProxyをリロードしてみましょう。

  1. sudo systemctl reload haproxy

次に、ホストに戻るためにコンテナからログアウトします。

  1. logout

ポートで受信した接続を転送するリバースプロキシとして機能するようにHAProxyを構成しました 80 他の2つのコンテナ内の適切なWebサーバーに接続します。 それをテストしてみましょう haproxy 実際には、リクエストを正しいWebコンテナに転送することができます。 次のコマンドを実行します。

  1. curl --verbose --header 'Host: web2.example.com' http://10.10.10.10

これにより、HAProxyにリクエストが送信され、HTTPが設定されます host ヘッダー。HAProxyが接続を適切なWebサーバーにリダイレクトするために使用する必要があります。

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

Output of "curl --verbose --header 'Host: web2.example.com' http://10.10.10.10" command
... > GET / HTTP/1.1 > Host: web2.example.com > User-Agent: curl/7.47.0 > Accept: */* > ... < <!DOCTYPE html> <html> <head> <title>Welcome to nginx on LXD container web2!</title> <style> ...

HAProxyはリクエストを正しく理解し、リクエストをに転送しました web2 容器。 そこで、Webサーバーは、以前に編集したデフォルトのインデックスページを提供し、テキストを表示します。 on LXD container web2. それでは、外部リクエストをHAProxyにルーティングして、世界中が私たちのWebサイトにアクセスできるようにしましょう。

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

パズルの最後のピースは、リバースプロキシをインターネットに接続することです。 ポートでインターネットから受信する可能性のある接続を転送するようにサーバーを設定する必要があります 80haproxy 容器。

HAProxyはコンテナにインストールされ、デフォルトではインターネットからアクセスできません。 これを解決するために、 iptables 接続を転送するルール。

The iptables コマンドには2つのIPアドレスが必要です。サーバーのパブリックIPアドレス(your_server_ip)およびのプライベートIPアドレス haproxy 容器 (your_haproxy_ip)、で取得できます lxc list 指図。

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

  1. sudo iptables -t nat -I PREROUTING -i eth0 -p TCP -d your_server_ip/32 --dport 80 -j DNAT --to-destination your_haproxy_ip:80

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

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

IPTablesの詳細については、IptablesFirewallの仕組みおよびIPtablesEssentials:一般的なファイアウォールルールとコマンドをご覧ください。

最後に、これを保存するには iptables 再起動後に再適用されるようにコマンドを実行し、 iptables-persistent パッケージ:

  1. sudo apt-get install iptables-persistent

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

2つのFQDNを設定している場合は、Webブラウザを使用して各Webサイトに接続できるはずです。 やってみよう。

2つのWebサーバーが実際にインターネットからアクセス可能であることをテストするには、ローカルコンピューターからそれぞれにアクセスします。 curl このようなコマンド:

  1. curl --verbose --header 'Host: example.com' 'http://your_server_ip'
  2. curl --verbose --header 'Host: web2.example.com' 'http://your_server_ip'

これらのコマンドは、サーバーのパブリックIPアドレスへのHTTP接続を確立し、HTTPヘッダーフィールドを追加します。 --header 手順5で行ったように、HAProxyがリクエストを処理するために使用するオプション。

これが最初の出力です curl 指図:

Output
* Trying your_server_ip... * Connected to your_server_ip (your_server_ip) port 80 (#0) > GET / HTTP/1.1 > Host: example.com > 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 web1!</title> <style> body { ...

これが2番目の出力です curl 指図:

Output
* Trying your_server_ip... * Connected to your_server_ip (your_server_ip) port 80 (#0) > GET / HTTP/1.1 > Host: web2.example.com > 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 web2!</title> <style> body { ...

どちらの場合も、正しいWebサイトが表示されます。

結論

HAProxyがトラフィックを転送する、それぞれ独自のコンテナ内に2つのWebサイトを設定しました。 このプロセスを複製して、それぞれが独自のコンテナーに限定された、さらに多くのWebサイトを構成できます。

MySQLを新しいコンテナに追加してから、WordPressなどのCMSをインストールして各Webサイトを実行することもできます。 このプロセスを使用して、古いバージョンのソフトウェアをサポートすることもできます。 たとえば、CMSのインストールにPHP5などの古いバージョンのソフトウェアが必要な場合は、Ubuntu 14.04をコンテナーにインストールできます(lxc launch ubuntu:t)、Ubuntu16.04で利用可能なパッケージマネージャーのバージョンをダウングレードしようとする代わりに。

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