KasmVNC (オープンソースの VNC) を使う

Desktop as a Service の Kasm Workspaces の内部で使われている KasmVNC を単独で利用する方法について記載します。KasmVNC はオープンソースとして公開されています。Linode で立ち上げた Linux サーバーの GUI を使う例として紹介します。後半では、VNC を使うときに気になるネットワーク転送量についても触れます。

Kasm Workspaces については下記の記事を参照してください。

https://qiita.com/110hideki/items/ec0820b6e5e657f939f1

# KasmVNC とは
KasmVNC は Linux 環境で動くリモートデスクトップサービスです。KasmVNC はブラウザーからアクセスでき、 VNC アプリケーションを必要としないのが特徴です。サーバーおよびユーザーレベルで YAML 形式によって簡単に設定をカスタマイズできます。

https://github.com/kasmtech/KasmVNC

# KasmVNC の動作条件
Kasm Technologies 社の Document に詳細な動作環境が記載されています。

https://www.kasmweb.com/kasmvnc/docs/1.0.0/install.html#hardware

本記事では Ubuntu 20.04 LTS、Tokyo Region、Linode 2GB (2GB Memory、1 CPU、1 Core、2TB Transfer) のプランで試します。2 Core 以上が推奨されていますので、業務で利用されるときは Linode 4GB プラン以上を使うのがおすすめです。

# KasmVNC のインストール

KasmVNC の GitHub から、最新バージョンのダウンロードページに行きます。

https://github.com/kasmtech/KasmVNC/releases

複数の .deb ファイルがあります。どれをダウンロードするかを確認するために、仮想サーバーの端末で、使っている CPU のベンダーを調べます。
```
% lscpu | grep AMD
Vendor ID:                       AuthenticAMD
```
AMD だと分かったので、``kasmvncserver_jammy_1.0.1_amd64.deb`` をダウンロードします。

```
wget https://github.com/kasmtech/KasmVNC/releases/download/v1.0.1/kasmvncserver_jammy_1.0.1_amd64.deb
```
ダウンロードしたファイルを使ってインストールします。
```
sudo apt-get install ./kasmvncserver_jammy_1.0.1_amd64.deb
```
パッケージを最新にします。
```
sudo apt update && apt upgrade
```

``vncserver`` を起動するためには、``ssl-cert`` グループが必要です。
```
sudo addgroup $USER ssl-cert
```

``vncserver`` を起動します。
```
vncserver
```
以下の選択項目がでます。
```
Creating default config /home/hideki/.vnc/kasmvnc.yaml
xauth:  file /home/hideki/.Xauthority does not exist

In order to control your desktop, you need a KasmVNC user with write
permissions. Select what action to take:

[1] Create a new user with write access
[2] Start KasmVNC without a user with write access

Provide selection number:
```

``1`` を選択して、KasmVNC にアクセスするためのユーザーアカウントを作成します。
```
Provide selection number: 1

Let's create a user.

Enter username (default: hideki):
Password:
Verify:
Created user "hideki"
Please choose Desktop Environment to run:
[1] Manually edit xstartup
1
/etc/ssl/private/ssl-cert-snakeoil.key: certificate file doesn't exist or isn't a file
```

ファイルへのアクセスの権限がないため、起動できませんでした。
```
sudo ls -l /etc/ssl/private/ssl-cert-snakeoil.key
-rw-r----- 1 root ssl-cert 1704 Feb 10 17:26 /etc/ssl/private/ssl-cert-snakeoil.key
```

``groups`` コマンドで ``addgroup`` した ``ssl-cert`` が登録されていません。
```
$ groups
hideki sudo
```

``/etc/group`` には登録されています。
```
$ egrep ssl-cert /etc/group
ssl-cert:x:118:hideki
```

再度ログインし直したら、正しい状態になりました。
```
$ groups
hideki sudo ssl-cert
```
もう一度 ``vncserver`` を起動します。
```
$ vncserver

New 'jammy:1 (hideki)' desktop is jammy:1

Users configured:
hideki (can use keyboard and mouse)

Log file is /home/hideki/.vnc/jammy:1.log

Creating default startup script /home/hideki/.vnc/xstartup
Starting applications specified in /home/hideki/.vnc/xstartup

Paste this url in your browser:
https://XXX.XXX.XXX.XXX:8444
```

# KasmVNC にアクセスする

``vncserver`` を起動したときに、アクセス元の URL が記載されています。その URL にアクセスします。デフォルトのポート番号は ``8444`` です。アクセスすると、下図のような HTTP 認証のサインが表示されます。``vncserver`` を起動した時に作成したユーザーアカウントとパスワードを入力します。
![kasm-login2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/7a95325a-674e-d510-5ddc-b56f86b2f817.jpeg)

ログインできた後の画面です。画面左側にコントロールパネルが表示されています。しかし、Ubuntu にデスクトップ環境をインストールしていないので、何もできない状況です。
![kasm-firstview.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/0013986b-63a4-360c-5e96-e835d5e73744.jpeg)

``ssh`` で接続した端末から、ubuntu 用のデスクトップ環境をインストールします。
```
sudo apt-get -y install ubuntu-desktop
```
リブートします。
```
sudo reboot now
```

リブート後、``ssh`` で再度ログインし、 ``vncserver`` を起動します。今度はデスクトップ環境が正しく表示されました。
![kasm-firstview-desktop.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/8678c59c-d3b0-53b9-7d7f-5615ca2984f7.jpeg)

Startup を終了したら、左上の ``Activities`` からアプリケーションを選択できるようになります。
![kasm-desktop-activities.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/a5dfe087-281b-8c4e-218e-f3df9768914c.jpeg)

ブラウザーがないのでインストールします。
```
sudo apt -y install firefox firefox-locale-ja
```

インストールが終了すると、画面に Firefox のアイコンが表示されます。
![ubuntu-firefox-browser.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/e53424cf-65e8-a90a-bb2f-83c28001c78e.jpeg)

# KasmVNC の停止

``vncserver`` のディスプレイ番号を取得します。
```
vncserver -list
```

表示結果です。ディスプレイ番号は ``:1`` であることが分かります。
```
$ vncserver -list

KasmVNC server sessions:

X DISPLAY #	PROCESS ID
:1		982
```
``vncserver`` のプロセスを停止します。ディスプレイ番号を指定します。
```
vncserver -kill :1
```
``vncserver`` コマンドの詳細はマニュアルを参照ください。
```
man vncserver
```

# KasmVNC の設定
``vncserver`` を起動すると以下のファイルが作成されています。
```
$ ls -lg .vnc .Xauthority .xsession-errors
-rw------- 1 hideki  160 Feb 10 18:19 .Xauthority
-rw------- 1 hideki  412 Feb 10 18:19 .xsession-errors

.vnc:
total 164
-rw-rw-r-- 1 hideki 154646 Feb 10 18:33 jammy:1.log
-rw-r--r-- 1 hideki     65 Feb 10 17:38 kasmvnc.yaml
-rw-rw-r-- 1 hideki      8 Feb 10 18:19 passwd
-rwxr-xr-x 1 hideki    553 Feb 10 17:53 xstartup
```
``.log`` はログファイル、``xstartup`` は X Window Manager の設定スクリプトです。``kasmvnc.yaml`` は KasmVNC の設定ファイルです。次の YAML 形式が記載されています。

```
logging:
  log_writer_name: all
  log_dest: logfile
  level: 100
```

カスタマイズするには、ドキュメントを参照します。

https://www.kasmweb.com/kasmvnc/docs/1.0.0/configuration.html

サーバー単位での設定は ``/etc/kasmvnc/kasmvnc.yaml`` で記入します。

# クリップボードへのコピー

クリップボードのコピーができるので、ホストマシンとのテキストの共有ができます。
![kasmvnc-clipboard.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/0654c895-3ddc-3f0f-c7e3-6a91181e0652.jpeg)

クリップボードのコピー機能を有効化するには、サーバーのコンフィグファイルを編集します。
```
sudo vi /etc/kasmvnc/kasmvnc.yaml
```

``runtime_configuration.allow_client_to_override_kasm_server_settings`` を ``true`` にします。
```
# runtime_configuration:
#   allow_client_to_override_kasm_server_settings: true
   runtime_configuration.allow_client_to_override_kasm_server_settings: true
```
クリップボードの機能は Data Loss Prevention 機能の一つとして提供され、細かく設定できるようになっています。詳細はドキュメントを参照してください。

https://kasmweb.com/kasmvnc/docs/latest/configuration.html#data-loss-prevention

# KasmVNC の制約
Kasm Workspace では対応している音声出力、ローカルホストとのファイルのアップロード/ダウンロードができないようです。

# Chrome Developer Tool で KasmVNC のリクエストを見る

Chrome の Developer tool で KasmVNC を使ったときのリクエストを調べます。最初に WebSocket で接続されています。このソケットは常時接続され、状態を監視しています。
![kasmvnc-websocket.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/6fb1a8f6-afb0-935b-1b4f-61c4f0728b0d.jpeg)

読み込まれたデータを Developer Tool の Preview で見るとイメージファイルの断片が見えます。
![kasm-image-streaming1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/52dea98e-7295-54f7-5ce1-03ed44905b01.jpeg)

ダウンロードされるファイルを見ると、パズルを組み立てているみたいで興味深いです。WebP も使われています。
![kasm-webp-streaming.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/7b41fcec-51db-6b6f-6c85-f4b4ecb745e4.jpeg)

動画を閲覧しているときも、ダウンロードされているのはイメージファイルでした。
![kasmvnc-youtube-webp.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/d77f0a2b-f60c-cb59-cb8b-321ebda21c25.jpeg)

素晴らしい技術ですね。

# Linode の LongView で状態を監視する
![longview-logo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/d3a5a673-bf56-026c-9e73-a8b762e96362.jpeg)
ブラウザーは KasmVNC (vncserver) から常にファイルをダウンロードしているので、CPU 処理やネットワークの使用量が気になります。Linode では LongView を使うことで、Linode Contol Panel から常に状態を監視することができます。

Linode にログインして、Longview から ``Add Client`` します。コマンドを Linux 上で実施するように促されます。もし上手くいかない場合は、以下のようにコマンドを分割して実行してください。一旦 ``longview.sh`` のファイルとしてダウンロードします。
```
curl -s https://lv.linode.com/DUMMY6C9-XXXX-XXXX-AA40A998C14DUMMY -o longview.sh 
```
root ユーザーで実行します。
```
sudo bash ./longview.sh
```
実行されていることを確認します。
```
ps axuw| grep longview
root       33825  0.9  1.7  43132 35104 ?        Ss   20:52   0:00 linode-longview
```
暫くすると、Longview にデータが見えてきます。
![Screen Shot 2023-02-10 at 10.56.12 PM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/2959e96e-52a4-5a87-a0c5-0f4682e9ed59.jpeg)

# データ転送の比較
macOS の Chrome ブラウザーから、YouTube 画像を見たときの比較が次のとおりです。

| 方法 | データ転送量 | リクエスト数 |
|:-----------|------------:|:------------:|
| macOS から直接視聴 (動画フォーマット)  | 82 MB        | 538 requests        |
| KasmVNC で起動した Firefox アプリから視聴(Quality: Medium)| 258 MB        | 147,660 requests  |
| KasmVNC で起動した Firefox アプリから視聴(Quality: Extreme)       | 528 MB        | 161,564 requests        |

予想はしていましたが、やはり動画配信フォーマットと比較するとかなり転送量は多くなっています。それでも、イメージをベースにリアルタイムで配信している中で頑張っているのかもしれません。動画は一定時間の webM ファイルのチャンクを送信されていたのに対し、KasmVNC では細かい差分のイメージを送信しているため、リクエスト数は圧倒的に多くなっています。その中で、カクカクしたりすることもなく、また、通常の動画として視聴できるのは驚きです。

## YouTube on Chrome on macOS
Chrome 上の表示です。
![macos-chrome-quality-medium-data-volume.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/d3cb99bd-e1ef-ff8a-e69b-f959dedd2020.jpeg)
YouTubeの画質は自動 (1080p60 HD) でした。
![macos-chrome-youtube-quality.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/da5c9807-3e9c-bda9-3143-2cf299d30551.jpeg)

## YouTube on Firefox on KasmVNC (Quality Medium) on Chrome on macOS
Chrome 上の表示です。
![kasmvnc-quality-medium-data-volume.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/ccf51dbf-7dd4-42e4-0251-c1249396214b.jpeg)

KasmVNC の Steram Quality の設定は Medium を使いました。
![kasmvnc-quality-medium-config.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/88e4c2ba-583e-df88-95b7-09f4aea55f02.jpeg)

### 画面イメージ
全ての評価は同じ macOS 上の Chrome で同じ開き方で比較しています。データは Chrome の Developer Kit の Network タブから取得しています。
![kasmvnc-quality-medium-waterfall-details.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/1a7e61a7-acff-631f-7901-3911338f08ec.jpeg)

## YouTube on Firefox on KasmVNC (Quality Extreme) on Chrome on macOS
Chrome 上の表示です。
![kasmvnc-quality-extream-data-volume.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/f443dcd8-19cc-a6fd-40c7-bc13225c9346.jpeg)

KasmVNC の Steram Quality の設定は Extreme を使いました。
![kasmvnc-quality-extream-config.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/c1a2ae33-037f-bb7a-c437-8cbb4b9f6829.jpeg)

# Longview で見えるネットワーク監視状況
KasmVNC のようなデスクトップサービスは、ローカルに表示されるデスクトップイメージをサーバーから配信しているため、サーバーから見た場合のアウトバウンド転送量が多くなります。Linode の Longview を使うとインバウンドとアウトバウンドの量が可視化できますが、アウトバウンドの量が多いことが分かります。
![longview-kasmvnc2localmac.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/a9a8eb61-60bd-3197-6db4-2b95f40947f6.jpeg)
デスクトップサービスを利用しない通常のアプリケーションでは、多くは逆で、インバウンドの量が多くなります。例えば、インターネットからブラウザーに対して動画を見るようなケースです。

# KasmVNC の転送量

KasmVNC の Quality を Extreme にしたケースでは 20 分間の動画視聴に 500 MB強 をダウンロードしました。このケースのデータを使って、開発者が Linux サーバーで一日 10 時間、20 日使うと仮定した場合、500 x 60 / 20 x 10 x 20 = 300 GB アウトバウンドを消費します。Linode であれば、最安の $5 のプランでも 1TB の転送量が入っていますので、転送量に対して課金される心配はなさそうです。

KasmVNC スタンドアローンで一日中使うケースはあまり想像できませんが、Kasm Workspaces のようなワークスペースを提供するサービスであれば、セキュリティ強化の目的で、1,000 人規模で特定のアプリケーションだけを利用させるケースもあります。その場合のアウトバウンド転送量費用は無視できなくなります。

# まとめ
Kasm Workspaces のコア技術である KasmVNC はブラウザー上で Linux の画面をストリーミング表示します。使った感じのストレスはないです。画質についても調整機能があります。インストールも簡単で、ブラウザーで動くので使い勝手が良いです。YouTube を視聴した時の転送量比較では、通常の動画ではなくイメージをベースとしたストリーム配信のため、 3.14 から 6.43 倍増加 (KasmVNC の Quality 設定が Medium (デフォルト)と Extreme の対比）しました。クラウドのデスクトップサービスだとアウトバウンド転送量が気になりますが、Linode のように egress コストが低いサービスは安心感があると思います。