[VPS] OpenVZのインスタンスを利用する場合の注意点

VPSを選ぶときに、「KVM」「OpenVZ」という2つの言葉をよく目にすることがあります。僕は、はじめてVPSを借りるときに価格性能比だけを重視してカゴヤのVPS(OpenVZのほう)を選んだのですが、後になって色々後悔しました。この記事では、OpenVZでできなかったこと(デメリット)や運用上の注意点を、KAGOYA CLOUD/2のVPSについても軽く触れつつ、書いていこうと思います。

KVM と OpenVZ とは?

KVM、OpenVZは、サーバ仮想化技術のひとつ。これらの詳しい解説はググれば腐るほど出てくるので割愛します。重要なのは、KVMは「ハイパーバイザ型のハードウェア仮想化」であるのに対し、「コンテナ型のOS仮想化」であるということです。KVMはOpenVZと比べてより深いレベルで仮想化を実現しています。OpenVZは各ゲスト間でカーネルを共有するので、一部機能は制限されますが、仮想化のレベルはKVMと比較して浅いので、仮想化によるオーバーヘッドは少ない(らしい)です。

OpenVZ でできなかったこと(デメリット)

実際にOpenVZのインスタンスを使ってみて、できなかったことや、つまづいたポイントを挙げていきます。

ちなみに、KAGOYA CLOUD/2 では、KVM、OpenVZ両方のインスタンスを作成することができます。

環境

  • KAGOYA CLOUD/2 の VPS(OpenVZ)
  • CentOS Linux release 7.4.1708 (Core)
  • CPU: 3コア/メモリ: 1GB~2GB(1GBを最低保証)/ SSD: 80GB

iptables の hashlimit が使えなかった

注: 2018年10月30日現在のKAGOYA CLOUD/2では使えるようになっています

hashlimitとは、iptablesの拡張モジュールのひとつで、これを使うと送信元IPアドレス、ポート番号などの単位でアクセス頻度の制限をすることができます。(DDos攻撃によるサーバー負荷をある程度抑えることができる)

OpenVZ Forum によるとhashlimitが使えるのはカーネルバージョン2.6.18以降であり、2018年1月時点で、カゴヤのOpenVZで動いていたのは2.6.18未満であったため、hashlimitが使えませんでした。ちなみに2018年8月時点でのカーネルバージョンは…

uname -r
2.6.32-042stab123.9

でした。このバージョンだとDockerとかは動かなそう。

そして、くどいようですがOpenVZは各ゲスト間でカーネルを共有するので各インスタンスからカーネルをアップデートすることはできません。VPSの場合、サーバーを管理している業者によってアップデートされるのを待つしかありません。これはhashlimitだけの問題ではなく、新しいカーネルバージョンを要求する機能は使えない可能性があるというのが真の問題となります。

IPマスカレード(NAPT)が使えない

OpenVPNのサーバーとして機能するように、NATの設定をしようとしてハマりました。各クライアントからのインターネットアクセスを全てサーバー経由で行う(redirect-gateway)ためには、一般的にはIPマスカレードが使われると思いますが、どうやらOpneVZのインスタンスからは使えないようです。これはOpenVZそのものに原因があるので、どの業者のVPSを使っても同じです。

この場合、ソースNAT(SNAT)で代用することができます。例えば、10.8.0.0/24からのインターネットアクセスを、venet0というネットワークインターフェースを経由して外部ネットワークへ流す場合、以下のように設定します。

#IPマスカレードの場合
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j MASQUERADE

#ソースNATで代用する場合
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j SNAT --to-source <サーバー側のグローバルIPアドレス>

一部のリソース制限がきつい

VPSを使う以上、CPU、メモリ、ディスクなどのリソースが制限されるのは当然ですが、それ以外のリソースも制限されています。

OpenVZのリソース制限は、以下のファイルに記述されています。

/proc/user_beancounters

このファイルの読み方は、後述

個人的に一番きつかったのは、iptablesに登録できるパケットフィルターのエントリ数制限です。カゴヤのOpenVZでは、200~400が上限に設定されています。ブラックリスト的な使い方をしていたり、複数のサービスを公開していたりすると全然足りないかもしれません。

もっと増やせないの?と思ったのですが、OpenVZの仕様上、エントリ数が200~300を超えるとパケットの処理が目に見えて低速化するので、仕方ないようです。

user_beancounters の読み方

catで中身を見ればOK

値をインスタンス側から変更することはできません。

$ sudo cat /proc/user_beancounters
Version: 2.5
       uid  resource                     held              maxheld              barrier                limit              failcnt
    xxxxx:  kmemsize                 34984413             46120960            107990581            118789639                    0
            lockedpages                     0                    0                 5272                 5272                    0
            privvmpages                323214               375940               524288               524288                    0
            shmpages                       62                 2092               127917               127917                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            numproc                        68                  138                 2636                 2636                    0
            physpages                  139250               441359                    0               524288                    0
            vmguarpages                     0                    0               262144               262144                    0
            oomguarpages               134796               140957               213195  9223372036854775807                    0
            numtcpsock                     10                   88                 2636                 2636                    0
            numflock                       21                   35                 1000                 1100                    0
            numpty                          2                    5                   80                   80                    0
            numsiginfo                      0                   66                 1024                 1024                    0
            tcpsndbuf                  235704              2519352              2519980              3599686               107951
            tcprcvbuf                  163840              9633688             25199804             35996860                    0
            othersockbuf                67048              1248048              1259990              2339695                    4
            dgramrcvbuf                     0               296480             12599902             12599902                    0
            numothersock                   59                   79                 2636                 2636                    0
            dcachesize               17912954             24293376             23585801             24293376                    0
            numfile                       886                 1435                42176                42176                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            numiptent                      59                   60                  200                  400                    0

列の値

説明
uid コンテナを識別するID
resource 対象のリソース
held 現在の使用量
maxheld (原則)起動してからの現在までの使用量の最大値
barrier リソースの制限設定。この2値がリソース制限にどのような影響を与えるかは、対象のリソースによって異なるが、おおむね barrier >= 制限値 >= limitとなるようである。 詳しくは行の値へ
limit
failcnt 制限によって拒否されたリソース要求の合計

行の値(抜粋)

説明
privvmpages

メモリ割り当ての上限。単位はページ。(通常1ページ = 4KB)heldがbarrierに達した時点で、メモリの割り当ては「優先度が高い」と判断されたもの(プロセスのスタック等)のみに制限される。

limit以上にメモリを確保することはできない。

なお、heldの値は割り当てが行われた量であって、実際に使用中とは限らない。

vmguarpages

メモリ割り当ての最低保証値。(単位:ページ)heldがbarrierに達するまでは、メモリ割り当ては常に成功する。

それ以降のメモリの割り当ての可否は、ホスト及び他のコンテナのメモリ使用状況による。limitの値は現バージョンでは無視される(特に意味は持たない)。

numproc プロセス+カーネルスレッドの上限数。limitが上限値。barrierには特に意味がなく、limitと同じ値が推奨される。
oomguarpages

OOM Killerに関する設定。

メモリ使用量+スワップ使用量+カーネルメモリ+ソケットバッファのメモリ使用量がbarrier以下であればOOM Killerによってプロセスが強制的に殺されることはない。barrierを超えると、最も使用量が大きいアプリケーションが強制的に終了させられる。failcntが増えるということは、OOM Killerが行われたという証拠。(単位:ページ)

numtcpsock TCPソケットの上限数。barrier = limit が推奨される。
numflock ファイルロックの上限数
numpty 擬似端末(SSHでのログイン等に使用される)の上限数。barrier = limit が推奨される。
tcpsndbuf TCPの送信バッファの上限(単位:バイト)
tcprcvbuf TCPの受信バッファの上限(単位:バイト)
numfile オープンできるファイルの上限数。barrier = limit が推奨される。
numiptent

iptablesのパケットフィルタのエントリ数の上限。barrier = limit が推奨される。

200~300以上の値を設定すると、目に見えてパケットの処理が遅くなるため、非推奨。

参考

上の表は、OpenVZ Virtuozzo Containers Wikiを和訳しただけなので、表に載っていないパラメータはそちらを参照。

まとめ

ここまでOpenVZのVPSのマイナス面ばかり挙げてしまいましたが、コスパではKVMと比較して高いレベルを誇っていると思います。

特に、税込み1000円以下で仮想3コアを使うことができる国内VPSは現状カゴヤのOpenVZ以外にはないと思います。

OpenVZの特徴を理解し、それが許容される用途であれば、かなり有効な選択肢になるのではないでしょうか。

あわせて読みたい

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です