1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ずんだもん「Ubuntu + Cockpit + Tailscaleで『どこでもKVM』環境を組んでみたのだ」(Sunshine併用)

1
Last updated at Posted at 2025-11-29

導入:なんでProxmoxじゃなくてUbuntu + Cockpit?

Image 1 Image 2

ずんだもん「おおつむぎ、新しくサーバ自作したのだ? 今回はProxmoxじゃなくてUbuntuにするって聞いたのだ。」

つむぎ「いやそれな〜。Proxmoxマジ便利ではあるんだけど、ホスト画面CLI前提だし、有線LAN必須だったりして、そこまで本格じゃないサーバをサクッと立てたいときにはビミョいんよね〜。」

  • Proxmox VE はDebian前提で、GPUドライバや最新Mesa対応はUbuntuより遅れがちになりやすい。
  • Ubuntu 24.04ならIntel Arc + Wayland + SunshineでAV1エンコーディングまで公式サポートが入っており、最新GPUを活かしやすい。

ずんだもん「だからホストをUbuntu 24.04 LTSにして、KVM + Cockpit + Tailscale + Sunshine で全部まとめてみたのか。」

つむぎ「要は“Ubuntuで全部盛りやっちゃおうぜ”ってノリね。いいじゃん〜。」

構成

image.png

つむぎ「環境こんな感じ〜。わりと盛りだくさんなんだけど、やってることはシンプル寄りだよ。」

  • OS: Ubuntu 24.04 LTS(デスクトップ)

  • 仮想化: KVM + libvirt + Cockpit(Web UI)

  • ネットワーク: Wi-Fi 6 接続のみ(有線なし)

  • GPU: Intel Arc(Core Ultra 世代 iGPU、Wayland + AV1 対応)

  • リモートアクセス:

    • VM管理系 → Tailscale + tailscale serve で Cockpit をHTTPS/TLS化
    • ストリーム → Sunshine (host) + Moonlight (iPad / Mac) でAV1/HEVC配信

ずんだもん「要するに、Proxmox級にリモートでいじれるUbuntuデスクトップKVMホストを、Wi-Fi環境だけで作ってみたってことなのだな?」

つむぎ「しかもIntel ArcでAV1キメてく、みたいな。ちょっと未来感あってアガる〜。」

全体の手順フロー

Image 1 Image 2

つむぎ「やることは大きく5ステップに分かれるよ〜。これ頭に入れとくと迷子らない。」

1. システム更新
2. Tailscale インストール・接続・`serve` 設定
3. KVM / libvirt / Cockpit / virt-manager のインストールと初期設定
4. ISO・仮想ディスク用ディレクトリの権限調整
5. Sunshine のセットアップ&自動起動(自動ログイン前提)

ずんだもん「そんなに手順は多くないのだな。LinuxだからCLIオンリーで環境できあがるのはメリットなのだ!」

ステップ1:システム更新

ずんだもん「まずはいつものやつなのだ。」

つむぎ「ここサボると後でパッケージ依存関係でバグるから、サクっとやっとこ〜って感じ。」

sudo apt update
sudo apt upgrade -y

ステップ2:Tailscale + serve で Cockpit をHTTPS化

2-1. Tailscale の導入

ずんだもん「公式スクリプトで一気に入れるのだ。」

つむぎ「これ一発でリポジトリ設定までやってくれるから、素直に乗っかるのが吉〜。」

curl -fsSL https://tailscale.com/install.sh | sh
  • install.sh はディストリを自動判定し、Ubuntu用の公式リポジトリを設定して tailscale をインストールしてくれる。

2-2. 起動&ログイン

つむぎ「ここでテイルネットデビューしちゃうわけ〜。」

sudo tailscaled &
sudo tailscale up
  • ブラウザが開くので、TailscaleアカウントでログインしてこのUbuntuホストをテイルネットに参加させる。

2-3. Cockpit(9090) を tailscale serve で公開

image.png

つむぎ「ローカルではCockpitを http://localhost:9090 で動かしておいてね〜。それをTailscaleでラップするイメージ!」

sudo tailscale serve --bg --https=443 http://localhost:9090

image.png

image.png

image.png

  • これで https://<ホスト名>.<テイルネット名>.ts.net にアクセスすると、Tailscale側でTLS終端 → Cockpit(9090)にリバースプロキシされる。

Cockpitが自己署名HTTPSのままなら、バックエンド検証を無視する版:

sudo tailscale serve --bg --https=443 https+insecure://localhost:9090
  • https+insecure:// は、自己署名などの不正な証明書チェックをスキップしてプロキシするための方法。

つむぎ「表側はTailscaleのちゃんとした証明書で、裏側は自己署名でもヨシ!っていう、おきがる構成ね〜。」

ステップ3:KVM / Cockpit / virt-manager

Image 1 Image 2

3-1. KVM & libvirt & virt-manager

ずんだもん「ここで仮想化ホストをインストールするのだ。」

つむぎ「ここ通れば“普通のUbuntuデスクトップ”が“ちゃんとしたハイパーバイザ”にクラスチェンジするから、ちょいワクワクするやつ〜。」

sudo apt update
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager

sudo systemctl enable --now libvirtd

sudo usermod -aG libvirt,kvm $USER
# または
# sudo adduser $(id -un) libvirt
# sudo adduser $(id -un) kvm
  • 再ログイン後、virt-manager からパスワードなしでローカルKVMホストに接続できる。

つむぎ「グループ追加したら、ちゃんと一回ログアウトしないと反映されないから、そこだけ注意ね〜。」

3-2. Cockpit + 仮想マシンプラグイン

ずんだもん「つぎはCockpit入れてWebブラウザから VM いじれるようにするのだ。」

つむぎ「Virt-Managerとかターミナルだけだとテンション上がらん人、ここからが本番だから〜。」

sudo apt update
sudo apt install -y cockpit cockpit-machines

sudo systemctl enable --now cockpit.socket

# UFWを使っている場合のみ
sudo ufw allow 9090/tcp
  • Cockpitの「仮想マシン」タブから、Webブラウザ経由でKVMゲストの作成・起動・コンソール接続ができる。

つむぎ「しかも Tailscale 経由で HTTPS だし、httpで警告でないサーバー、なんか“ちゃんとしてる感”マシマシで最高〜。」

ステップ4:ISO・ディスクイメージ用ディレクトリの権限調整

ずんだもん「ISO置き場は libvirt 標準の /var/lib/libvirt/images/ をそのまま使うのだ。」

つむぎ「ここごちゃると“ISO見えませ〜ん”って怒られるから、先にサクっと揃えとこ〜。」

sudo chown -R root:root /var/lib/libvirt/images/

sudo find /var/lib/libvirt/images/ -type d -exec chmod 755 {} \;
sudo find /var/lib/libvirt/images/ -type f -exec chmod 644 {} \;
# 必要なら ISO だけ個別に
# sudo chmod 644 /var/lib/libvirt/images/*.iso
  • libvirt/qemu のデフォルト設定では、root 所有・644 のISOや qcow2 を問題なく読み込める。

ステップ5:Sunshine + 自動起動(自動ログイン)

5-1. 自動ログインを有効化

  • GNOMEの「設定 → ユーザー → 対象ユーザー → 自動ログイン」を有効化。
  • あるいは gdm3 の設定で同等の自動ログインをオンにする。

つむぎ「Sunshine はデスクトップセッション前提だから、ここサボると“あれ起動してなくね?”ってなるから注意〜。」

5-2. systemd ユーザーサービス

ずんだもん「Sunshine をログイン後に自動起動させる設定なのだ。」

つむぎ「一回作っとけば、毎回ポチポチ起動しなくていいから QOL 爆上がり〜。」

#!/usr/bin/env bash
set -euo pipefail

# ==== Ubuntu バージョン自動判定 ====
if command -v lsb_release >/dev/null 2>&1; then
  DISTRO_ID=$(lsb_release -is | tr 'A-Z' 'a-z')
  DISTRO_VER=$(lsb_release -rs)
else
  # /etc/os-release から取得
  if [[ -r /etc/os-release ]]; then
    # ID と VERSION_ID をそれぞれ取り出す
    DISTRO_ID=$(grep -E '^ID=' /etc/os-release | cut -d= -f2 | tr -d '"' | tr 'A-Z' 'a-z')
    DISTRO_VER=$(grep -E '^VERSION_ID=' /etc/os-release | cut -d= -f2 | tr -d '"')
  else
    echo "ERROR: lsb_release も /etc/os-release も利用できないため、Ubuntuバージョンを判定できません。" >&2
    exit 1
  fi
fi

if [[ "$DISTRO_ID" != "ubuntu" ]]; then
  echo "ERROR: このスクリプトは Ubuntu 専用です。検出ID: ${DISTRO_ID}" >&2
  exit 1
fi

# Sunshine の .deb が用意されているのは 22.04 / 24.04 系のみ(現時点)[web:139][web:142]
case "$DISTRO_VER" in
  22.04*|24.04*)
    echo "[*] Detected Ubuntu ${DISTRO_VER}"
    ;;
  *)
    echo "ERROR: サポートしていない Ubuntu バージョンです: ${DISTRO_VER}" >&2
    echo "      (22.04 または 24.04 系のみ対応)" >&2
    exit 1
    ;;
esac

DISTRO=ubuntu
ARCH=amd64
REPO="LizardByte/Sunshine"

workdir="$(mktemp -d)"
trap 'rm -rf "$workdir"' EXIT

echo "[*] Fetching latest release info..."
api_url="https://api.github.com/repos/${REPO}/releases/latest"
deb_pattern="sunshine-${DISTRO}-${DISTRO_VER}-${ARCH}\.deb"

deb_url="$(
  curl -fsSL "$api_url" \
  | grep -Eo "https://[^\"']*${deb_pattern}" \
  | head -n 1
)"

if [[ -z "${deb_url:-}" ]]; then
  echo "ERROR: 最新の ${DISTRO}-${DISTRO_VER}-${ARCH} 向け .deb が見つかりませんでした。" >&2
  exit 1
fi

echo "[*] Downloading: $deb_url"
cd "$workdir"
curl -fsSL "$deb_url" -o sunshine-latest.deb

echo "[*] Installing sunshine-latest.deb ..."
sudo apt install -y ./sunshine-latest.deb

echo "[*] Writing user systemd unit..."
unit_dir="$HOME/.config/systemd/user"
mkdir -p "$unit_dir"

cat > "$unit_dir/sunshine.service" <<'EOF'
[Unit]
Description=Sunshine Game Stream Host
After=graphical-session.target
Wants=graphical-session.target

[Service]
Type=simple
ExecStartPre=/bin/sleep 5
ExecStart=/usr/bin/sunshine
Restart=on-failure
RestartSec=5s
Environment=DISPLAY=:0
Environment=XDG_RUNTIME_DIR=/run/user/%U
Environment=XDG_SESSION_TYPE=x11

[Install]
WantedBy=default.target
EOF

echo "[*] Enabling user service..."
systemctl --user daemon-reload || true
systemctl --user enable sunshine || true
systemctl --user restart sunshine || true

echo "[*] Done. Current status:"
systemctl --user status sunshine --no-pager || true

  • /usr/bin/sunshine のパスは which sunshine で確認して合わせる。

5-3. 有効化

つむぎ「ちゃんと起動するかテストしてから恒常運用に入るの、大事〜。」

systemctl --user daemon-reload
systemctl --user start sunshine
systemctl --user enable sunshine
  • 再起動すると「起動 → 自動ログイン → graphical-session.target 到達 → Sunshine 起動」の流れになる。

ずんだもん「これで物理ホスト再起動しても勝手に Sunshine が動くのだ!」

実際に触ってみるのだ(Cockpit編)

Image 1 Image 2

つむぎ「Tailscaleでつないだ先から、Cockpitはこう見えたよ〜。」

image.png

image.png

  • iPad / Mac のブラウザから https://<ホスト名>.xxx.ts.net で Cockpit ダッシュボードに問題なくアクセス可能。TLS証明書の更新はTailscale側で自動処理。
  • UIはレスポンシブ対応でiPadでも使えるが、VNC コンソールをタッチだけで操作するのは厳しく、外部キーボード・マウスがほぼ必須。
  • iPad向けのSPICEクライアントは有料のものが多く、WindowsやLinuxクライアントの方が選択肢あり。

つむぎ「“とりまブラウザでVMオンオフして、細かい操作はちゃんとしたクライアントでやる”って割り切りが一番ストレス少ないかも〜。」

Sunshine編

ずんだもん「今度はデスクトップストリームなのだ。」

つむぎ「ここがVMの管理上重要~。うまく動けば便利でテンション上がるとこ〜!」

image.png

  • iPad mini の Moonlight クライアントでは、Sunshine側でAV1を有効にするとAV1ストリームとして接続され、ビットレートを抑えつつ低遅延で動作。
  • macOS版 Moonlight は現状HEVC中心で、セッション開始に数秒待たされるなど、Windowsホスト時と似た挙動。ただし実用上は問題ないレベル。
  • Windows配列キーボードでAppleデバイスを操作すると、いくつかキーの挙動に違和感が出る場面がある(ショートカット周りなど)。

つむぎ「Wi-Fiでも“あ、これ普通にいけるやつじゃん”って感じのレイテンシだったよ。LANケーブルひきたくない民にはだいぶ希望ある〜。」

まとめ

つむぎ「で、やってみてぶっちゃけどうだった〜?」
ずんだもん「まとめると、こうなのだ!」

  • Tailscale は Entra ID(Microsoft Entra ID)などIdPとのSSO連携ができ、tailscale serve でHTTPS終端と証明書更新を自動化できるので、ゼロトラスト + 簡易リバースプロキシとしてかなり扱いやすい。
  • Cockpit はKVMの上に薄いWeb UIを載せているだけなので導入が軽く、Proxmoxほどの本格ハイパーバイザは不要だが「ブラウザからVMを起動・停止したい」ケースには最適。
  • 2025年時点のUbuntu 24.04 + Intel Arc ドライバはWayland/AV1含めて成熟しており、Sunshineと組み合わせて低遅延ストリーミングが可能。
  • ただし、Moonlight側(特にmacOS/iOS版)のコーデック対応や最適化状況にはまだ制限があり、クライアントデバイスによってAV1/HEVCの挙動差が出る点には注意が必要。

つむぎ「総じて、“Proxmoxほどガチじゃないけど、それなりにちゃんとした仮想マシン管理サーバ欲しい”って人には、この構成かなりアリって感じだね〜。」

スタバにて

Image 1 Image 2

ずんだもん「つむぎ、これでUbuntuデスクトップでPC的に使いつつ、TailscaleもCockpitもSunshineも勝手に立ち上がってサーバーとしても使えるようになったのだ!」

つむぎ「え、やば。電源ボタンポチって、カフェラテ作って戻ってきたら、もうiPadからVMもゲームもいじれるってこと?それ、もはやクラウドギャルハウスじゃん。」

ずんだもん「クラウドギャルハウスの意味が分からんのだ....。それはともかく、Wi‑Fiだけで有線LANいらない、証明書もTailscale serveが自動更新してくれるのは良いのだな。」

つむぎ「それな〜。これならスタバからiPhoneでもいけるし。てか外で VM 再起動してるギャル、世界でウチくらいじゃね?

ずんだもん「つむぎ、こないだも寺で座禅してたと思ったら、“悟ったから VM のスナップショット消すわ〜”って言ってたのだ!」

つむぎ「煩悩は消すものでしょ?スナップショも同じ♡」

ずんだもん「“家でも座禅したいから、お坊さんにも Tailscale 入れてもらおう♡” とか言い始めて困ったのだ!」

つむぎ「いいじゃん。これからはゼロトラスト坊主の時代だし?」

ずんだもん「お坊さんに IAM ロール付けようとしないでくれなのだ!」

利用キャラクター

  • ずんだもん:VOICEVOX:ずんだもん
  • つむぎ:PIXIV:りょうごさん
    本記事で使用しているキャラクター画像の著作権は、それぞれの権利者に帰属します。
    非商用目的での利用に基づき掲載しています。
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?