えんでぃの技術ブログ

えんでぃの技術ブログ

ネットワークエンジニアの視点で、IT系のお役立ち情報を提供する技術ブログです。

Linux PC 構築関連リンク集

20200927134745

はじめに

2020年8月に新しいパソコンを購入し、そこにLinux をインストールしました。
そして、それをセットアップする過程で得られた知見を可能な限り書き留めてきました。

本記事では、書き溜めてきた記事のリンクを分類して貼っていきます。
今後も同様の記事があればリンクを追加していきますので、ぜひ活用してください。

パソコン本体の購入 (NUC10i5FNH)

愛用のデスクトップPCの故障をきっかけに、10万円でメモリ64GBのミニPCとして、NUCを購入しました。
買い物リスト、構築手順を公式リンクとセットでわかりやすくまとめました。

NUC10 購入にあたり、必要なもの

endy-tech.hatenablog.jp

NUC10のセットアップ手順

endy-tech.hatenablog.jp

Fedora Server のインストール

Fedora のインストール手順をスクリーンショット付きでまとめました。
パソコン用途に着目したパーティションの切り方を是非参考にしていただきたいです。

RHELCentOSを使う方もそのまま参考にできます。

endy-tech.hatenablog.jp

Linux デスクトップ環境の初期設定

GUI踏み台、普段遣いのパソコンの選択肢はWindowsだけではありません。
進化が進んで使い勝手が大幅に向上した Linux デスクトップのセットアップの仕方を解説します。
FedoraとCinnamon をベースに書いていますが、他のディストリビューションやデスクトップ環境をお使いの方にも応用できます。
是非参考にしてみてください。

Cinnamon Desktop のインストール手順

Cinnamon のインストール手順を紹介しています。
Windowsユーザー目線でCinnamon の良いところも言及しています。

endy-tech.hatenablog.jp

Linux における日本語入力の設定方法

iBus + Mozc でLinux の日本語入力のセットアップ方法を紹介しています。
iBus + Mozc を選択した理由についても言及しています。

endy-tech.hatenablog.jp

Linux のブラウザが抱える問題の解決方法

Linux のブラウザ特有の癖を解消する方法を紹介しています。
マウススクロールの高速化、動画再生用コーデックの追加、Google Chrome のインストール方法に触れています。

endy-tech.hatenablog.jp

Linux で音が出ない問題の切り分け方法と解決策

Linux で音が出ない問題、非常によくあります。
本記事ではその切り分け手順、及び解決策を紹介します。
特にNUC10にLinuxを入れている方は問題に該当するので、必見です。

endy-tech.hatenablog.jp

Linux無線LANが繋がらない時の対処法

Linux無線LANを有効化してもSSIDが表示されない問題に対する解決策を2つ紹介します。
また、「デスクトップだから...」といった理由で無線LANがなくても困らない方向けにも、「使わないなら無線を無効化すべき」である理由について書いています。

該当する方はぜひ参考にしてください。

endy-tech.hatenablog.jp

KVMの初期設定と使い方

KVM, QEMU, libvirt というOSSを組み合わせることで、LinuxVMを作成できます。
機能性はVirtualBoxVMware Workstation に劣らないばかりか、VMware vSphere に相当する可能性も秘めていると考えています。

そんなKVMを基礎理論から学び、導入し、VM検証に利用する中で得られた知見を皆様にも共有します。

KVM, QEMU, libvirt の概要

それぞれのOSSがどのように役割分担して仮想マシンを形作っているのか、調べた内容を共有します。
KVMとは一体何者なのか、何となく掴める内容になったと思います。

endy-tech.hatenablog.jp

KVMの初期設定、CLI (virt-install, virsh) によるVM作成

KVMlibvirtの初期設定手順から、CLIによってVMを作成するところまで紹介します。
KVMは動作要件を満たすのが思いの外難しいです。
トラブルシューティングの情報も断片的に掲載されていることが多いのですが、それらをこの記事で整理しました。

endy-tech.hatenablog.jp

Cockpit GUI によるKVM操作

Cockpit はLinux マシンを可視化・管理するGUIです。
追加パッケージを入れることで、Cockpit からKVM環境を操作して、VMの作成や編集を行うことができます。
Cockpit の機能は発展途上ですが、使い勝手が良いこととRedHat社によって推奨されていることから、Cockpit を今のうちに使っておいて損はないと思います。
使い始めるのはとても簡単です。

endy-tech.hatenablog.jp

Virtual Machine Manager GUI によるKVM操作

Virtual Machine Manager は、Cockpit と同様にKVMを操作できるGUIツールです。
Cockpit がWEBベースなのに対し、Virtual Machine Manager はデスクトップ環境やWindow Manager 上で動作します。
CLI (virshなど) ほどではありませんが、Cockpit と比較してGUIからできることが今のところは多いです。
今後はCockpit が流行る方向で開発が進んでいきそうですが、当面はVirtual Machine Manager も併用すると便利なことも多いです。

endy-tech.hatenablog.jp

Linuxを更に便利に使うためのTips

Linuxの便利機能や便利ツールに関する情報を集約します。

おすすめのLinux Terminal、Tilix の紹介

高機能なターミナルといえばTerminator なども有名ですが、Tilixは以下の利点があります。

  • 不具合が少ない (というか、ない)
  • 機能が充実している (これはTerminatorも同等)
  • 通常のウィンドウとQuakeモードを両立できる (これはTerminatorでもできる)

他にもただのセットアップに終わらず、こだわり抜いたカスタマイズ、トラブル修正方法を紹介しています。
Linux使いの方は是非見てください。

endy-tech.hatenablog.jp

Linux のバックアップツール、Timeshift と rsync

GUI で簡単に設定可能で、高速に動作するシステムバックアップツールであるTimeshift の特徴、使い方についてまとめています。
定期差分バックアップがお手軽に取得できます。
差分バックアップは「前の世代を消したら壊れる」ような複雑で遅くて危うい方式ではなく、どの世代も順不同で高速に削除できるため安心です。

endy-tech.hatenablog.jp

endy-tech.hatenablog.jp

Timeshift はシステムバックアップ用のツールです。
データバックアップ用としてrsyncと組み合わせることで、より完全なバックアップを取得できます。
以下の記事では、これら2つのツールを使い分けるべき理由と、rsyncの具体的な使い方について紹介しています。

endy-tech.hatenablog.jp

LinuxのDesktop Entryの書き方

LinuxデスクトップにMenuという機能があります。
WindowsのStart Menu、MacのLaunchpadやSpotlightと同じく、アプリケーション名で検索して素早く開くことができます。

このアプリケーション一覧のボタンを作り、クリックしたときに内部的にどんなコマンドを実行するかを定義するのがDesktop Entryです。

凝って書くと長くなりますが、シンプルに書けばわずか7行です。

Menuにアプリケーションを追加表示したいなら、Desktop Entryを自分で書いちゃいましょう。
この記事にそのやり方が書いてあります。

endy-tech.hatenablog.jp

FedoraへのSlackインストール

2022年3月1日以降、Fedora公式のRPMリポジトリでSlackの最新版をインストールできなくなりました。
SlackがFedoraへのサポートを打ち切ったためです。

この記事では、RPMの代替手段としてSnapによるSlackインストール手順を紹介しています。
この手順であれば、Fedoraは引き続きSlack公式のSnapリポジトリにアクセスし、Snapパッケージをコマンドによってインストール・更新できます。

endy-tech.hatenablog.jp

おわりに

今後もオリジナリティのある情報があれば記事追加・リンク集を更新していきますので、よろしくおねがいします。

はてなブログのスターやTwitterでイイネをくださる方、いつもありがとうございます。
励みになっています。

Virtual Machine Manager GUI によるKVM操作

Virtual Machine Manager logo

前の記事

virsh, Cockpit によるVM操作環境のセットアップ手順を紹介しました。

endy-tech.hatenablog.jp

endy-tech.hatenablog.jp

お伝えしたいこと

Virtual Machine Manager (virt-manager) のインストールと、画面についてざっくり紹介します。

前提

本記事で紹介する手順は、以下の記事でKVM, libvirt の初期設定が完了していることが前提となります。

endy-tech.hatenablog.jp

また、Virtual Machine Managerの導入にはGUI環境 (※) が必須です。
GUI環境がない場合は、Cockpit の利用をご検討ください。
(※) デスクトップ環境、またはWindow Manager

参考までに、過去記事を2つ貼っておきます。

↓デスクトップ環境の一例として、Cinnamon Desktop のインストール手順です。
endy-tech.hatenablog.jp

↓Cockpit のインストール手順と画面紹介です。
endy-tech.hatenablog.jp

Virtual Machine Manager とは

デスクトップ環境、またはWindow Manager 上で動作する、libvirtベースのGUIツールです。
本記事ではQEMU+KVMGUIから操作する用途に焦点を当てて紹介します。

Virtual Machine Manager のインストール

インストールコマンドはFedoraを前提にしています。
別のディストリビューションをお使いの方は読み替えてください。

以下のコマンドで Virtual Machine Manager をインストールします。

sudo dnf install virt-manager

まだの方は、コンソールログインするために Virtual Machine Viewerもインストールしましょう。

sudo dnf install virt-viewer

Virtual Machine Manager の起動

GUIのメニューから Virtual Machine Managerで検索して実行するか、CLIから virt-manager を実行することで起動します。

URIの指定

初回起動時、Virtual Machine Manager はデフォルトで qemu:///system に接続します。
変更したい場合は、File > Add connectionから新しいコネクションとしてqemu:///sessionなどを追加します。
その後、必要に応じて下図の赤枠部分を右クリックして、既存のコネクションを削除します。

virt-manager1

過去の記事でお伝えしたとおり、私としてはqemu:///systemをおすすめします。

XML編集の有効化

Virtual Machine Manager では、VM や pool 構成のXML定義ファイルを確認できます (≒virsh edit)
デフォルトでは、XMLの中身を見るだけで編集はできません。

しかし、以下の設定を変更することでVirtual Machine Manager から XML を編集できるようになります。

Edit > Preferecnces > Generalタブ > Enable XML editingのチェックをいれる

VMの作成

基本的には、RedHat社のドキュメント通りの手順です。

access.redhat.com

ここではポイントのみ記載します。

  • VM作成を開始するには、以下の赤枠部分を選択します

virt-manager2

  • インストールメディアを選択します
  • ISOイメージファイルを選択します (virt-install --cdrom) OSに応じたハードウェアの最適化オプションを指定します (virt-install --os-variant)
    • 例えば、fedora33などを指定します
    • わからない場合はgenericでも動作しますが、性能が大幅に下がります
    • 指定可能なキーワードは、 osinfo-query os コマンドで確認できます
  • メモリサイズ、CPUコア数を指定します
  • ディスクサイズを指定します
    • この画面でManageを選択すると、pool の管理画面に遷移します
    • 本来の目的である「既存のディスクの選択」に加え、pool の作成/削除/起動/停止が可能です
    • virsh pool-*相当の操作が可能なイメージです
  • 最後にVMの名前と仮想ネットワークを決めます

VMへのコンソールログイン

Virtual Machine Manager自体にコンソール画面を出す機能がありますが、解像度に上限があります。

Virtual Machine Viewer (virt-viewer) であれば任意の解像度に拡大/縮小できて便利なので、代わりにこちらを使いましょう。

Virtual Machine Viewerを起動する方法は、こちらの過去記事を参照してください。

コンソールログイン後のマウスカーソルの開放

コンソール画面をクリックすると、マウスカーソルがVMの中に移動します。
Left Ctrl + Left Alt でマウスカーソルが開放され、ホストOS側の制御に戻ります。

VMのクローン

トップ画面でVMを右クリックしてクローンできます。

virt-manager5

スナップショットの管理

VMをダブルクリックして開いた後の画面で、スナップショットの作成・削除・ロールバックも可能です。

virt-manager6

(参考) ホストに挿したUSBのマウント

この操作はCockpitではまだ対応しておらず、Virtual Machine Manager や virt-xml コマンドで実施します。

virt-xmlコマンドについては未検証ですが、下記URLや、本セクションの末尾に貼ったXMLが参考になると思います。
ただこのやり方だとXMLファイルを作る必要があるようなので、正直GUIの方が楽だと思います。

外付けHDDをVMにマウントする手順を例に紹介します。
事前に、前のセクションで紹介したXML編集の有効化設定を実施しておく必要があります。
また、操作対象のVMは電源を落としておく必要があります。

まずは、接続したいホスト側デバイスの情報を確認します。
事前に外付けHDDが東芝製とわかっているので、マークをつけた行だとあたりがつきます。
Canvio Deskググると、これが外付けHDDの製品名だとわかりました。
このデバイスは、ベンダーIDが0x0480、製品IDが0xd011だとわかります。

$ lsusb

Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0480:d011 Toshiba America Inc Canvio Desk  #★
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 8087:0026 Intel Corp. 
Bus 001 Device 006: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 005: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 001 Device 004: ID 1ea7:0066 SHARKOON Technologies GmbH [Mediatrack Edge Mini Keyboard]
Bus 001 Device 002: ID 214b:7250 Huasheng Electronics USB2.0 HUB
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

別の方法として、usb-devicesコマンドもあります。
出力が長いのが難点ですが、External USB 3.0という私にとっては見覚えのある表記が良いヒントになりました。
また、同じ製品を複数接続している場合はSerialNumberが参考になると思います。

$ usb-devices

# (省略)
T:  Bus=02 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#=  2 Spd=5000 MxCh= 0
D:  Ver= 3.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs=  1
P:  Vendor=0480 ProdID=d011 Rev=03.16
S:  Manufacturer=TOSHIBA
S:  Product=External USB 3.0
S:  SerialNumber=20180204010442
C:  #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=8mA
I:  If#=0x0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usbfs
# (省略)

さて、USB情報が確認できたところで、Virtual Machine Manager の操作に移ります。
トップ画面でVMを選択してからOpenボタンを選択し、VMの詳細画面を開きます (またはVM名をダブルクリック)。

virt-manager3

続いて、青いアイコンの「i」マークから、ハードウェアの詳細構成を表示します。
そして左下の「Add Hardware」を選択します。

virt-manager7

左のメニューからUSB Host Deviceを選択し、DetailsタブからVMに搭載したいUSBデバイスを選択します。

virt-manager8

XMLのタブに移動します。
ここでVendor IDとProduct ID が0x0000のままだと、設定確定の際にエラーになってしまいます。
また、デタラメな値を入れてもVM起動時にエラーになりました。
先ほどlsusbコマンドで調べた値をきちんと入力してから設定を確定します。

virt-manager9

設定を確定すると、以下の通りデバイスが追加されました。
USBデバイスは同じ画面の右下にあるRemoveボタンでも外せると思いますが、VM側で「USBの取り外し」ボタンを押すことでも登録解除されていました。

virt-manager10

virt-manager11

(参考) Virtual Machine Manager は必要か?

RHEL8においてはVirtual Machine Manager よりも Cockpit が推奨されているものの、Cockpitの機能はまだ十分ではありません。
Cockpit は使い勝手に優れており将来性もありますが、GUIでより多くの操作に対応するには、現状ではVirtual Machine Managerも必要です。

とはいえ、Virtual Machine Manager を導入するにはデスクトップ環境が必要となります。
デスクトップ環境がない場合には、Cockpit と virsh の併用が基本形となります。

繰り返しになりますが、できることの範囲はvirsh > Virtual Machine Manager > Cockpit になります。
使い勝手の良さは Cockpit > Virtual Machine Manager > virshだと思います。
もし試せる環境があるのであれば、全てのツールを触ってみてから、自分に合う組み合わせを探っていただくのが良いでしょう。

私は全部を使い分けています。
基本的にCockpit を使いますが、できないことが出てきたらVirtual Machine Manager, virsh の順番に試していくのが基本です。

まとめ

Virtual Machine Manager のインストール方法と、画面イメージを中心に紹介しました。
Cockpit の方がモダンな見た目ではあるものの、Virtual Machine Manager の方がサポートしている機能はまだ多い状況です。

私個人としては、Cockpit を中心としつつ足りない機能を CLI や Virtual Machine Manager で補うのが今のところ一番好みの使い方です。
皆さんのオススメの使い方があれば、是非コメントやTwitterで教えてください。

Linux PC 構築関連リンク集

endy-tech.hatenablog.jp

次の記事

VM作成/削除、CMROM挿入、起動順序設定などの基本操作のまとめは、以下の記事を参照ください。
CLI/GUIの両方についてまとめてあります。

endy-tech.hatenablog.jp

Cockpit GUI によるKVM操作

cockpit-apple-touch-icon

前の記事

KVMlibvirtの初期設定、及びlibvirt CLI (virt-install, libvirt) について基本操作を紹介しました。

endy-tech.hatenablog.jp

お伝えしたいこと

Cockpit から QEMU+KVM を操作するための初期設定を紹介しつつ、イメージが湧きそうなスクリーンショットを貼りたいと思います。
Cockpit はわかりやすい画面構成なので、細かい使い方については説明不要かなと思います。
使い方で迷った場合は、libvirtの基本として前の記事を参照してみてください。

前提

以下の記事でKVM, libvirt の初期設定が完了していることが前提となります。

endy-tech.hatenablog.jp

Cockpit のインストール

Cockpit本体をインストール、有効化します。
Fedoraの場合はデフォルトでインストールされています
※cockpit.socket は初めから有効化されています

sudo dnf install cockpit
sudo systemctl enable --now cockpit.socket

更に、cockpit からVMを管理できるように、追加でcockpit-machinesをインストールします。
このコマンドにより、cockpit のメニューにVirtual Machinesが追加されます。

sudo dnf install cockpit-machines

Cockpit へのアクセス

http://localhost:9090 にアクセスすると、cockpitのログイン画面が出てきます。
通常のLinuxと同様にID/パスワードを入力することでログインできます。

cockpit-login

Cockpit による VMの管理

VM一覧の表示

Virtual Machinesのタブを開くと、VMがリストアップされます。
画面の通りですが、ここで以下の操作が可能です。

  • Storage pool の作成、削除、変更
  • Network の作成、削除、変更
  • VMの作成、削除、クローン、起動、停止、一時停止、強制終了

cockpit-vm1

VMの詳細表示

#VM一覧の画面でVM名 (上図の赤枠部分) を選択すると、VMの詳細情報とコンソールアクセス用の画面に切り替わります。

このページでは以下のような操作が可能です。

  • CPU, Memory 割当の変更
  • ディスク、ISO、ネットワークのつけ外し
  • 自動起動のON/OFF、起動順序の指定
  • リソースグラフ、基本情報 (Hostname, MAC/IP Address) の表示

cockpit_vm_details

Launch Remote Viewerを選択すると、downloadというファイルがダウンロードされます。
downloadファイルを開くと、Remote Viewerが起動してコンソールアクセスできます。
URLを指定する必要はありません。
downloadファイル自体は開いた直後に自動削除されるので、downloadフォルダを汚すこともありません。
非常に使い勝手が良いです。

cockpit-vm2

VMの作成

#VM一覧の画面から "Create VM" を選択すると、VMの作成画面が出ます。
設定項目はvirt-managerと同じです。

一点だけ補足すると、"Operating system"にはvirt-install--os-variant相当の情報が入ります。
性能の最適化のため、インストールしようとしているOSに近いものを選択することが推奨されます。

...私のバージョンでは、Operating systemの選択肢が少なかったです。
例えば、無選択と同等のGeneric OSも表示されませんでした。
もし困った場合には、以下のリンクを参考にvirt-installコマンドかvirt-manager (GUI) によるVM作成をご検討ください。

cockpit_create_vms

(参考) Cockpit はどの程度オススメできるか?

まず、RHEL8においては、Virtual Machine Manager を非推奨とし、今後はCockpitをメインにサポートする動きになっています (参考)
また、Cockpit は画面構成が洗練されていて使いやすく、なおかつWEBアクセス可能なのでデスクトップ環境を必須としていません。

まとめると、以下の点でCockpit を評価できます。

  • Red Hat社によって推奨されている
  • 使い勝手に優れているGUI
  • デスクトップ環境を必須としない (WEBベース)
  • 無償のOSS

ただし、Cockpit でできることは限られています。
今後機能は拡充されていくとは思うのですが、現状ではVMとpool 周りの基本操作や基本情報の表示に限られています。
VMの起動・停止・コンソールアクセス・作成・削除・クローン、仮想ネットワークの作成と削除はCockpit にて可能なので、普段遣いとしてはそれほど困りません。
一方で、既存の仮想ネットワークの編集やcdromドライブへのISOファイルの紐づけなどは、Cockpitではまだ対応されていません。
仮想ネットワークの編集はvirshで、cdromドライブへのISOファイルの紐づけはvirshかVirtual Machine Manager にて可能です。

できることの幅は virsh > Virtual Machine Manager >> Cockpit という状況です。
一方で、私の主観に基づく使い勝手の評価は Cockpit > Virtual Machine Manager > virsh です。

結局のところ、私の環境ではvirsh, Virtual Machine Manager, Cockpit を全て併用しているのが現状です。
やりたいことに応じて、Cockpit > Virtual Machine Manager > virsh の優先順位で使い分けています。
デスクトップ環境がない場合は、virsh と Cockpit の併用でも問題ないと思います。

まとめ

cockpit のインストール、及びVMの管理画面を紹介しました。
細かい操作方法は省きましたが、libvirt CLI の基礎知識があれば直感的に操作できるのではないかと思います。

libvirtベースのツールとして、これまでにvirsh, Virtual Machine Manager, Cockpit と使ってきましたが、使い勝手の面ではCockpit が一番のお気に入りです。
ただ、対応機能の幅では virsh > Virtual Machine Manager >> Cockpit なので、やりたい操作によって使い分けるのが良い形であると私は考えています。

Linux PC 構築関連リンク集

endy-tech.hatenablog.jp

次の記事

次の記事では、Virtual Machine Manager のインストール手順と画面イメージを紹介します。
前提としてデスクトップ環境相当が必要となりますが、2021年現在においてはCockpitよりも多くの操作に対応しています。

endy-tech.hatenablog.jp

VM作成/削除、CMROM挿入、起動順序設定などの基本操作のまとめは、以下の記事を参照ください。
CLI/GUIの両方についてまとめてあります。

endy-tech.hatenablog.jp

KVMの初期設定、及びvirsh, virt-installによるVM作成

linux-kvm-logo
引用元:linux-kvm.org

前の記事

前回はKVM, QEMU, libvirt の概要について紹介しました。

endy-tech.hatenablog.jp

お伝えしたいこと

本記事では、KVM+QEMUによる仮想化システムのインストール手順と、libvirt CLI (virt-install, virsh) によるVM作成手順を紹介します。
その後、KVMが本当に正しく構成されているのかを確認する手順と、正しく構成されていなかった場合の対処法について紹介します。

libvirtベースのCLI/GUIツールの概要については、前の記事のlibvirt を利用している製品を先にお読みください。
libvirt ベースのGUIツールについては、次の記事で紹介します。

QEMUKVMlibvirt のインストールは非常に簡単です。
ただ、libvirtの初期設定、使い方、KVMが動かない時のトラブルシューティングを含めた結果、記事が長くなってしまいました。
手順上読まなくても問題ない部分には (参考) をつけましたので、不要と感じたら読み飛ばしてください。

本記事の末尾にオススメの解説動画も貼りました。
Arch Linux をモデルとした内容ですが、本記事と同様の紹介がされています。
文字よりも動画がお好みの方は、ぜひチェックしてみてください。
動画中の解説は英語です。
日本語がお好みでしたら、やはり私の記事を読んでください!

QEMUのインストール手順

以下のコマンドで、KVMに対応したCPUアーキテクチャ (x86) に対応するQEMUをインストールします。

sudo dnf install qemu-kvm

KVMのインストール手順

KVMLinuxカーネルモジュールとして初めから組み込まれているので、特にインストールは不要です。

KVMの動作確認 (1/2)

さて、ここでKVMの動作確認をします。
KVMの動作確認は2段階に分けて行います。

まず、ここではKVMとCPUの仮想化支援機能に関わるカーネルモジュールがそれぞれロードされていることを確認します。
以下のコマンドを実行してください。

lsmod | grep kvm

# kvm_intel             319488  0
# kvm                   823296  1 kvm_intel
# irqbypass              16384  1 kvm

上述のように、kvmkvm_intel、またはkvmkvm_amdのいずれかが表示されれば、まず問題ありません。
もしkvmkvm_intelが表示されない場合は、(参考) KVMが動作しない場合のトラブルシューティングにて問題を解消してください。

その上で、VMを1つも起動していないときはkvm_intel、またはkvm_amd の行の一番右の列が 0 であることを確認してください。
これは、kvm_intel、またはkvm_amdモジュールが他のプログラムによって利用されていないことを表しています。

この後、VMを実際に作成・起動した上でもう一度lsmodコマンドを実行します。
その状態で、kvm_intel、またはkvm_amd行に対応する数値が1以上の値になっていれば、KVMは正しく動作していることになります。
VM起動後に行うKVMの動作確認は、KVMの動作確認 (2/2)にて実施します。

コンソール接続用アプリケーションのインストール

VMにコンソール接続するためのアプリケーションをインストールします。
アプリケーションはGUIのプログラムであるため、Linux上で使う場合はGUI (デスクトップ環境やWindow Manager) が必要です。
KVMLinuxで動作させつつリモートのWindowsからコンソール接続する構成であれば、Windows側にRemote Viewerを入れるのに特に制限はありません。

ここでインストールしたアプリケーションは、後に#(参考) VMへのコンソール接続で使うことになります。

Virtual Machine Viewer のインストール

Virtual Machine Viewerは、VMにコンソール接続して画面表示するGUIツールです。
従って、GUI環境がなければ起動できません。

KVM仮想化を提供しているマシンがローカルで動作している場合には導入を推奨します。
または、libvirtのconnectionでネットワーク越しにKVMサーバに接続している構成でも、Virtual Machine Viewerを使えます。

以下のコマンドでインストールします。

sudo dnf install virt-viewer

Remote Viewer のインストール

アクセス元のLinuxから見てKVM仮想マシンがリモートで起動している場合は、Remote Viewerで接続します。
SPICEやVNCなどのプロトコルにより、ネットワーク越しにコンソール接続します。
Remote Viewerを使う際もGUI環境が必要です。

余談ですが、Cockpitをお使いの方もGUI操作でコンソール接続する際、Remote Viewerがあると便利です。

localhostを指定することでローカルの仮想マシンにも接続できますが、ローカルの場合はVirtual Machine Viewerの方が使い勝手が上です。

以下のコマンドでRemote Viewerをインストールします。

sudo dnf install remote-viewer

アクセス元がWindowsの場合は、Windows版のRemote Viewer を以下の公式サイトからダウンロード、インストールします。
virt-viewerと記載がありますが、これをインストールすると実際にはRemote Viewerもインストールされます。
https://virt-manager.org/download/

libvirtの初期設定

CLIVMを作成する

今回は、デスクトップ環境がなくても動作するCLIにて今回は進めたいと思います。

必要に応じて、GUIツールを後から追加インストールすることも可能です。
どのGUIツールをインストールしたとしても、必ず依存関係でCLIツールもインストールされます。
一旦GUIツールのことは気にしないこととして、先に進みましょう。

libvirtのインストール

以下のコマンドでlibvirtをインストールします。
libvirtvirt-installは導入必須です。
virt-topは任意なので、不要と感じたらスキップしても問題ありません。

# 必須
sudo dnf install libvirt virt-install

# 任意
sudo dnf install virt-top

インストールの内訳は以下の通りです。

パッケージ名 中身
libvirt libvirtdCLI/GUIツールからハイパーバイザー (QEMU+KVM) にAPI連携する
virshコマンドにより、Disk,仮想NWを作成する
・同コマンドでVMを起動・停止・削除する
virt-install virt-installコマンドにより、VMを新規作成する
virt-cloneコマンドでVMをクローンする
virt-top virt-topコマンドにより、VMのCPU,RAM,Disk利用状況を可視化する

libvirtdの起動

以下のコマンドでlibvirtd の自動起動を有効化しつつ、今すぐ起動します。
libvirtベースのツールは、libvirtdを介してハイパーバイザーを操作するので、libvirtdの起動は必須です。

sudo systemctl enable --now libvirtd

ユーザーグループの設定

libvirtqemu:///systemセッションで使うにあたり、libvirtを利用するユーザーをlibvirtグループに所属させる必要があります。
qemu:///system の意味については(参考) qemu:///system と qemu:///session の違いで、グループ設定が必要な理由は1. libvirtグループへの所属で補足します。

以下のコマンドによって、現在のユーザーがlibvirtd特権プロセスにアクセスするための権限を付与します。

usermod --append --groups libvirt `whoami`

(任意) qemu:///system をデフォルトにする

毎回 --connect を指定するのは面倒なので、デフォルト値を指定します。
この手順は必須ではありません。
qemu:///systemを使っている方のみ任意で実施してください。
qemu:///sessionを使っている方は、既にqemu:///sessionが一般ユーザーのデフォルト値なので、本セクションの手順は実施不要です。

~/.config/libvirt/libvirt.conf を作成し、以下のように記述します。

uri_default = "qemu:///system"

以下のコマンドにより、QEMUが接続するハイパーバイザーのURIを確認します。

virsh uri
# qemu:///system

以下のようにエラーが出た場合、#libvirtdの起動の手順を忘れている可能性があります。
リンク先を参照して対処してください。

virsh uri
# error: failed to connect to the hypervisor
# error: Failed to connect socket to '/var/run/libvirt/virtqemud-sock': No such file or directory

ここで設定を入れた方は、以降の手順で--connect qemu:///systemオプションを省略しても問題ありません。
本記事の解説においても、以降は--connect qemu:///systemの記載は省略します。

ちなみに、Virtual Machine Managerのデフォルト値はqemu:///systemです。
Virtual Machine Managerとvirshで見えるVMやpoolなどが異なる場合は、利用しているConnectionが異なる可能性があるので注意してください。
このあたりは最初にハマりがちな罠だったりします。
Virtual Machine Manager側の設定方法は、Virtual Machine Manager GUI によるKVM操作 #URIの指定を参照してください。

(参考) デフォルトURI決定の優先順位

デフォルトのURIは、以下の優先順位で探索されます。

  1. 環境変数LIBVIRT_DEFAULT_URI
  2. クライアント設定ファイル:uri_default = "qemu:///system"
  3. 応答があるまで、各種ハイパーバイザーを順に試す

ここでは、「2. クライアント設定ファイル」によって指定します。
クライアント設定ファイルは、以下の2箇所に配置します。

  • rootユーザ用:/etc/libvirt/libvirt.conf
  • 一般ユーザ用:$XDG_CONFIG_HOME/libvirt/libvirt.conf~/.config/libvirt/libvirt.conf

man libvirtdによると、$XDG_CONFIG_HOMEが未定義の場合は、$HOME/.config/になるようです。
従って、今回更新すべきファイルは~/.config/libvirt/libvirt.confということになります。

pool 作成の事前準備

VMを作成する前に、pool の設定を変更します。
poolには、VMのディスクイメージファイル (*.qcow2) や、ISOイメージファイルの保管場所を設定します。
本来はstorage pool が正しい呼び方なのですが、本記事においては省略して pool と呼ぶことにします (man virsh でもしばしば pool と省略表記されます)。

さて、pool を作成する事前準備として、まずディレクトリをどこにするか決めます。
詳細は2. イメージファイルのパーミッションに後述しますが、VM作成に必要なISOイメージファイルや、VMのディスクイメージファイルはqemuユーザーによってアクセスできるようパーミッションを設定する必要があります。
それを踏まえて、事前に保存先のディレクトリをどこにするか決めておいてください。

今回は、/home/shared/libvirt/images/にディスクイメージファイルを、/home/shared/libvirt/images/isos/にISOイメージファイルを保存します。
/home/shared/images/isos/配下は、rhelubuntuなどお好みでフォルダ分けします。
/home/sharedは、sharedグループに属するユーザーであれば誰でもアクセス可能なディレクトリとして作成します。
qemuユーザーもsharedグループに属すように設定します。

(※) 私の環境はパソコン用途を想定しているため、/homeファイルシステム容量を大きくしています。したがって、/home配下にイメージファイルやVMDKファイルなどの大容量ファイルを置くために、今回のようなフォルダ構成としました。なおご参考までに、libvirt-daemon RPMパッケージをインストールすると/var/lib/libvirt/imagesをデフォルトで生成します。今回のフォルダ構成は自分なりにアレンジを加えたものの、libvirt/images/というフォルダの切り方はデフォルト構成を踏襲しました。ファイルシステムの設計は皆様それぞれだと思いますので、自分の環境にあった置き場所をご検討ください。

以下のコマンドで上述の構成にできますので、よろしければそのままご利用ください。

# sharedグループを作成し、qemuと一般ユーザーを加える
sudo groupadd shared
sudo usermod --append --groups shared $(whoami)
sudo usermod --append --groups shared qemu

# ディレクトリを作成し、qemuからアクセスできるようオーナー・権限を変更する
sudo mkdir -p /home/shared/libvirt/images/iso
sudo chown -R root:shared /home/shared/
sudo chmod -R o-rwx /home/shared/

pool 作成

まず、pool を定義 (define) します。
このコマンドにより pool の構成情報を記述したXMLファイルが生成し、libvirt によって管理されるようになります。
本記事はvirshの紹介記事なのでCLIで実施していますが、GUI環境があればvirt-managerやcockpitからもpoolの作成は可能です。

virsh \
pool-define-as default dir \
--target /home/shared/images/

defineなどのlibvirt用語について知りたい方は、(参考) libvirt (virsh) の用語も参照してください。

(参考) pool 作成コマンドの補足

コマンドの意味について補足します。
不要な方は読み飛ばしてください。

まず、syntax は以下のようになります。

virsh \
pool-define-as <pool-name> <type> \
--target <target-path>

各キーワードの意味は、以下のようになります。

<pool-name> は、pool の名前です。
KVMのイメージファイルを格納するpoolとして、defaultを作成することをお勧めします。
その理由は、2つあります。

  • Virtual Machine Manager (GUI)が起動時に default というプールを勝手に作ってしまうため
  • 他のvirshコマンドでも、pool名の指定を省略した場合にdefaultを自動的に指定するものがあるため

<type> は、ファイルの置き場所によって変わります。
ローカルの特定ディレクトリをpoolとして使用し、ディレクトリ配下にイメージファイルを格納する場合はdirを指定します。
その他の type に関する情報は、libvirt公式サイトに情報がありますが、dir以外はあまり使わない印象です。

--target は、type=dir の場合に使用するオプションで、poolと対応するディレクトリパスを指定します。
--typeに指定する値によって指定すべきオプションが変わるので、CLIだと結構わかりづらいです。
Cockpit操作であればGUIの選択肢がtypeに応じて良い具合に切り替わるので、このあたりが直感的に操作できて便利です。

pool の起動・自動起動設定

virsh pool-define-as は pool を作成しただけで起動はしていません。
pool の起動、及びOSと共に自動起動する設定も必要です。

Linuxのデーモンに対して systemctl enablesystemctl start するのと似たような考え方ですね。

# pool の起動
virsh pool-start default
virsh pool-start images

# pool の自動起動
virsh pool-auto-start default
virsh pool-auto-start images

pool の確認

最後に、作成したpool を確認します。

pool を一覧表示するには、pool-list を使います。
デフォルトでは起動していない pool が表示されないので、全て表示したい時は --all もつけます。
--details で詳細表示できます。

pool の完全な設定情報を確認したい場合は、 pool-edit を実行します。
pool-edit は構成情報のXMLを開くので、ステータスは確認できませんが設定情報は全て確認できます。
XMLを編集して保存すると設定が書き換わるので、注意してください。

# pool の一覧表示
virsh pool-list

# pool のXML構成情報表示/編集
virsh pool-edit default
virsh pool-edit images

(参考) pool の停止・削除

この手順は基本実施不要です。
もしpool を間違えて作ってしまい、削除したくなったときは以下の流れで実施します。

  • pool の停止 (destroy)
  • pool の削除 (undefine)

補足ですが、VMの通常停止を shutdown、強制停止(VMのプロセス kill) をdestroyと呼びます。
pool の停止の場合は、常に destroy と呼ばれます。

VM/pool の削除は undefine と呼びます。
pool 作成時に実施した define の反対で、XMLファイルを削除します。
削除操作は、対象を停止させた上で実施する必要があります。

コマンドとしては、以下のようになります。

# virsh pool-destroy <pool-name>
# virsh pool-undefine <pool-name>

ISOファイルの準備

VMを作成するのに必要なISOファイルをダウンロードし、上記の手順で作成した pool の target directory に格納してください。

その際、ISOファイルのパーミッションに注意してください。
ISOファイルは、qemuユーザーによってアクセスできる必要があります。
本ブログに従ってディレクトリを構成した場合は、以下の2コマンドを実行することで適切に権限設定できます。

sudo chown -R root:shared /home/shared/
sudo chmod -R o-rwx /home/shared/

VMの作成

VMを作成するには、以下のコマンドを実行します。
紹介しているコマンドは例ですので、環境によって一部変更してください。

virt-install \
--name test \
--memory 1024 \
--vcpus 2 \
--disk size=8 \
--cdrom /home/shared/libvirt/images/isos/fedora/Fedora-Server-dvd-x86_64-32-1.6.iso \
--os-variant fedora32 \
--noautoconsole

コマンドラインオプションの意味については、次の(参考) VM作成コマンドの補足を参照してください。

VMの作成コマンド実行時に警告やエラーが出た場合は、(参考) virt-install コマンドの WARNING/ERROR 対策を参照してください。

(参考) VM作成コマンドの補足

virt-installのオプションの意味を補足します。
補足が不要な方は読み飛ばしてください。

情報源はman virt-installです。

オプション 意味
--name VM_NAME 作成するVMの名前を指定する
--memory MEM_SIZE VMのメモリサイズをMiB単位で指定する
--vcpus CPU# 仮想CPUコア数を指定する
--disk size=VOL_SIZE 仮想ディスクのサイズをGiB単位で指定する
--cdrom PATH_TO_ISO VMのOSをインストールするためのイメージファイル (ISO) へのフルパスを指定する
--os-variant OS (Distribution) の名前と紐づく値をセットする。
指定することで、libvirtdが指定したOSに最適な仮想ハードウェア (特にvirtio) を選択する
このパラメータは必須ではないが、正しく設定することで性能が著しく向上する。
指定を省略した場合、ISOファイルをURL指定で取ってくる場合のみ自動認識される。
--os-variant に指定可能な文字列は、osinfo-query osコマンドにより確認可能
--noautoconsole VM作成直後にVirtual Machine Viewer (virt-viewer) のコンソールを自動的に開かないようにする。
このオプションを入れない場合、コマンド末尾に&を付けてバックグラウンド実行とすることで、Virtual Machine Viewerが起動した後にプロンプトが戻ってくるようにするのが良い

VMの起動確認

VMが起動していることを確認します。
--allオプションをつけると停止しているVMも含めて表示されます。

virsh list

KVMの動作確認 (2/2)

ここまでの手順でVMが起動できているはずですので、KVMの動作確認をします。
KVMの動作確認 (1/2)でも触れたとおり、KVMが正しく動作していれば、kvm_intel、またはkvm_amdカーネルモジュールの利用回数の部分が1以上の値になっているはずです。

以下のコマンドを実行してください。
kvm_intel に対応する一番右の値が 4 になっています。
この数字が1以上なので、KVMは正しく動作しています。

lsmod | grep kvm

# kvm_intel             319488  4
# kvm                   823296  1 kvm_intel
# irqbypass              16384  1 kvm

本セクションでKVMの動作確認ができたら、VMの削除を参照しつつ、動作確認用のVMを削除します。
ここまで問題なく完了したら、KVMのセットアップは完了です。
お疲れ様でした。

【重要】動作確認時の注意

KVMが正しく動作して作成したVMと、KVM利用に失敗してQEMU (TCG: Tiny Code Generator) にフォールバックして作成されたVMは、完全に別物と理解してください。

実際に試してみたところ、以下のような挙動になりました。

  • qemuで作成したVM
    • KVMが無効でも有効でもVMを起動できる
    • KVMが利用可能な状態でVMを起動しても、QEMU単体 (TCG) で起動する
  • kvm+qemuで作成したVM
    • KVMが利用可能な場合は、通常通り起動する
    • KVMが利用できない場合は、エラーが出て起動しない

特に重要なのは前半の事実で、トラブルシューティングが完了してKVMが利用可能となった後に、QEMUベースで作成したVMを起動しても、kvm_intel、またはkvm_amdの使われている数は0のままということです。

KVMトラブルシューティングをした後は、必ずVMを作り直した上で動作確認してください。

(参考) VMへのコンソール接続

この手順は、LinuxGUI環境 (≒デスクトップ環境) をインストールした方のみが実行可能な手順です。
CLI、またはGUIによってVirtual Machine Viewerを起動し、コンソールログインします。

Virtual Machine Viewerは、基本的にlibvirtで接続したサーバー (--connect qemu:///system) に対してローカルな接続を提供します。
言い換えると、基本的にlocalhostに対するコンソール接続に使います。

リモートで実行しているKVM仮想マシンにコンソール接続したい場合は、Remote Viewerを使用します。

Virtual Machine Viewer (CLIから起動)

まずはCLIからの起動手順を紹介します。
以下のコマンドを実行するだけです。

virt-viewer &

すると、以下の画面から起動中のVMが表示されるので、選択して接続します。

virt-viewer1

成功すれば、コンソール画面が表示されます。

virt-viewer2

以下のように、VM名を引数として指定することでVMを明示的に指定することも可能です。

virt-viewer test &

普段CLIKVMを操作する方は、virsh startVMを起動した後、virt-viewer &でコンソール接続する使い方が動線としてはスムーズかなと思います。

Virtual Machine Viewer (GUIから起動)

GUIのMenuからVirtual Machine Viewerを起動して接続することもできます。
以下のように、Menuから検索して起動するだけです。

virtual_machine_manager_on_the_menu

環境によっては、検索してもヒットしないこともあります。

多くのGUIアプリケーションは、Menuから起動するために必要なDesktop Entry (*.desktopファイル) を/usr/share/applications/配下などに自動配置するため、Menuから問題なく起動できます。
しかし、私の環境 (Fedora35 + Cinnamon Desktop) ではVirtual Machine Viewerのdesktopファイルが自動配置されなかったので、手動で作成します。

以下のテキストファイルを~/.local/share/applications/virt-viewer.desktopに配置してください。
そうすれば、デスクトップ環境のMenuからVirtual Machine Managerを開けるようになるはずです。
再ログインする必要はありません。

[Desktop Entry]
Name=Virtual Machine Viewer
Exec=virt-viewer
Comment=Display the graphical console
Terminal=false
Icon=virt-viewer
Type=Application

Desktop Entryについてより詳細を知りたい方は、以下の記事を参照してください。

endy-tech.hatenablog.jp

(参考) Remote Viewer

Remote Viewerとは、Remote Desktopのようなリモート接続のウィンドウを出すプログラムです。
KVMをリモートサーバーで動かしているときに使うことがあるので、参考までにやり方を書いておきます。

今回の例では私の環境の都合でlocalhostにRemote Viewerで接続していますが、基本的な考え方は同じです。

まず、Remote Viewerを使いたい場合は以下のコマンドでRemote Viewerをインストールしておきます。

sudo dnf install remote-viewer

そして、以下の手順で接続します。

まず、コンソールアクセスするためのURLを先に確認します。
1台目の起動であれば、spice://127.0.0.1:5900 と表示されます。
2台目であれば、spice://127.0.0.1:5901 とポート番号が1刻みで増えます。
慣れれば確認するまでもなくポート番号が予想できます。

virsh domdisplay test
# spice://127.0.0.1:5900

デスクトップのメニューから "Remote Viewer" で検索し、Remote Viewerを起動します。
そして、出てきたウィンドウに上記URLを入力して接続します。

virt-viewer3

成功すれば、コンソール画面が表示されます。

virt-viewer2

以下のようにCLIからRemote Viewerを起動することも可能です。

remote-viewer
# または
remote-viewer spice://localhost:5900

ポート番号の指定など面倒なので、ローカル接続にはVirtual Machine Viewerを使うことをおすすめします。

(参考) Cockpit からの起動

Cockpitの画面でVM名をクリックし、「Launch Remote Viewer」を選択するとdownloadという名前のファイルがダウンロードされます。
このファイルをクリックして開けば、Remote Viewerが開きます。

downloadファイルは、開いた直後に自動的に削除されるので、基本的にフォルダが汚れることはありません。
とても優秀です。

詳しくは、次の記事で紹介します。

VMの削除

まず、削除対象のVMを停止します。
VMの停止は、以下の2種類があります。

  • 通常停止(shutdown): VMにshutdown するよう命令を送る
  • 強制停止(destroy): VMプロセスを kill する (≒電源長押しによる停止)

強制停止は、何らかの理由で (※) 通常停止ができない場合のみ使うイメージです。
経験上、作成したばかりのVMでOSが未インストールの場合はshutdownを受け付けないので、destroyで強制停止します。
これから削除するVMに対しては、気軽に強制停止しても問題ありません。
(※) VMが無応答だったり、KVMではなくQEMU単体で動作している場合はshutdownできないこともあります

virsh shutdown test
# または、virsh destroy test

VMが停止したことを以下のコマンドで確認します。

virsh list test

VMを削除する時に気をつけたいのは、オプションを指定しない限り、VMに紐づくディスクファイルは削除されないことです。
オプションを指定するために、まずは以下のコマンドでブロックデバイス名を調べます。
ちなみに、VMのことをlibvirt用語でdomainとも呼びます。
domblklistは、"list domain's block files" という意味になります。

virt-install--os-variants を指定した場合は、最適な仮想ハードウェアとしてvda (virtio) が選択されているはずです。
逆に--os-variants を指定しなかった場合は、低速なhda (仮想IDE) が選択されます。

virsh domblklist test

続いて、以下の手順では、--storage オプションを指定することで、VMに紐づくディスクファイル(qcow2) も一緒に削除するようにしています。
--snapshots-metadata--managed-save は、関連するスナップショットや保存データも削除するオプションです。
スナップショット作成やVMの保存をしていなければ特に意味はありませんが、不要データを綺麗に削除するために指定しても損はないと思います。
--remove-all-storage は、virsh domblklist でISOファイルが表示されていた場合、ISOファイルまで削除されてしまうので、このオプションはあまり使いません。

# "vda" の部分は、virsh domblklist の出力によっては "hda" に変更する
virsh \
undefine \
--domain test \
--storage vda \
--snapshots-metadata \
--managed-save

(参考) virt-install コマンドの WARNING/ERROR 対策

virt-install コマンド実行時、警告メッセージが出ることがあります。
ここでは、警告のメッセージについて対処法を補足します。
警告が出なかった場合は読み飛ばして結構です。

WARNING KVM acceleration not available, using 'qemu'

このメッセージが出たら、KVMが正しく動作していません。
KVMの動作確認 (2/2)からKVMが動作していないことを確認できたら、(参考) KVMが動作しない場合のトラブルシューティングで原因調査の上、対処してください。

XXX may not be accessible by the hypervisor.

具体的には、以下のようなメッセージです。

WARNING  /home/shared/libvirt/images/isos/fedora/Fedora-Server-dvd-x86_64-32-1.6.iso may not be accessible by the hypervisor. 
You will need to grant the 'qemu' user search permissions for the following directories: ['/home/shared']

このメッセージが出た場合、その下のメッセージを確認してください。
以下のメッセージが続いていたら、VMは作成できているので無視しても問題ありません。

Starting install...
Allocating 'test.qcow2'
Domain installation still in progress. 
You can reconnect to the console to complete the installation process.

このメッセージは、libvirt側でイメージファイル(iso)、またはディスクファイル(qcow2) へのアクセス権限があると断定できない場合に発生します。
今回の構成ではsharedグループによってqemuに権限を与えているのですが、どうやらlibvirtはグループの中身までは見てくれないようです。

対応策は、考えうる限り3案あります。
私は案1で対処しました。

案1. ACLによって明示的にqemuユーザーに権限を割り当てる

ACLについては、@ITの記事がわかりやすかったです。

以下のように、ISOファイルとディスクファイルを格納している各ディレクトリの中身が見えるように権限設定すれば、警告は回避できます。
1行目と3行目ではディレクトリの場合のみ、qemuユーザに対してrwx権限を与えています。
2行目では全ファイルにおいて、qemuユーザに対してrw権限を与えています。

sudo setfacl -Pm u:qemu:rwx /home/shared/
sudo setfacl -PRm u:qemu:rw /home/shared/libvirt/
find /home/shared/libvirt/ -type d | sudo xargs setfacl -Pm user:qemu:rwx

以下のコマンドで設定内容を確認します。
ls -ldは、+フラグがつくところが確認ポイントです。

ls -ld /home/shared/
getfacl /home/shared/
getfacl /home/shared/libvirt/

操作を取り消したい場合は、以下のコマンドでACLを削除できます。

# sudo setfacl -Pb /home/shared/
# sudo setfacl -PRb /home/shared/libvirt/

ACLの弱点は、chmodの実装よりもわかりづらくなるところですね。
この操作は該当のディレクトリにファイルを配置する度に実行する必要があるので、私の環境では/home/shared/set_permissions.shに以下のスクリプトを配置しています。
ファイルを配置する度にシェルスクリプトを実行すれば、いい感じに権限が付与されます。
ご利用の際は、事前に中身を理解するようにしてください。

#!/bin/bash
echo setting a permission and owner to /home/shared...
echo sudo password may be required.
echo

echo command: "sudo chown -R root:shared /home/shared/"
sudo chown -R root:shared /home/shared/

echo command: "sudo chmod g+rw,o-rwx /home/shared/"
sudo chmod -R g+rw,o-rwx /home/shared/

echo command: "sudo setfacl -Pm u:qemu:rwx /home/shared/"
sudo setfacl -Pm u:qemu:rwx /home/shared/

echo command: "sudo setfacl -PRm user:qemu:rw /home/shared/libvirt/"
sudo setfacl -PRm user:qemu:rw /home/shared/libvirt/

echo command: "find /home/shared/libvirt/ -type d | sudo xargs setfacl -Pm user:qemu:rwx"
find /home/shared/libvirt/ -type d | sudo xargs setfacl -Pm user:qemu:rwx

echo
echo change completed!

案2. qemuユーザーをディレクトリのオーナーにする

ACLを使わず、chown でqemuユーザーをディレクトリのオーナーにすることでも回避できます。
私の場合は、以下の理由で案2は不採用としました。

  • 共有ディレクト/home/shared にファイルを置きたい
  • /home/sharedのオーナーを qemu:shared にするのは少し抵抗があった。root:sharedにしておきたい

案3. 無視する

悪影響のないメッセージなので単純に無視するのも一つの手です。
virshとVirtual Machine Manager では警告が出ますが、Cockpit の場合は警告は出ません。

正直、案3. でも全く問題ありません。
グループによって権限を与えているのであれば、本来は警告メッセージが出る方がおかしいのですから。

ERROR Guest name 'test' is already in use.

既に 'test' という名前のVMが存在しています。
virsh list --all で確認できます。

対処方法はVMの名前を被らないようにするか、VMを削除することが挙げられます。

VMを削除する場合は、事前にブロックデバイス名を確認します (vda/hda)。

# ディスクファイル (qcow2) がhdaかvdaかを確認する
virsh domblklist test

続いて、VMを削除します。
その際、--storageオプションで一緒に削除したいブロックデバイス名を指定します(vda/hda)。

# "vda" の部分は、必要に応じて "hda" に変更する
virsh destroy test
virsh undefine --storage vda test

(参考) KVMが動作しない場合のトラブルシューティング

本記事の手順を実施してもKVMが動作しなかった場合は、以下の情報を参考にしてみてください。
私の環境 (NUC10+Fedora32) では運良く全くトラブルが発生しなかったので、紹介する内容は全て未検証であり、机上で調査した情報になります。

KVMの動作要件

KVMを利用するには、以下の条件を満たしている必要があります。

  1. CPUが仮想化支援機能をサポートしていること
  2. BIOSが仮想化支援機能を無効化していないこと
  3. KVMカーネルモジュールがロードされていること
  4. /dev/kvmの権限が正しく設定されていること

上記動作要件それぞれについて、以下で確認方法と対処法を紹介します。

(参考) まずは確認ツールを実行してみる

libvirtに同梱される確認ツールを実行することで、QEMU (+KVM) の動作要件を満たしているか確認できます。

  • PASSがついていれば問題なし。
  • WARNがついていても、恐らく動作します
  • FAILがついている場合は、恐らく正しく動作しません

WARNとFAILの解釈は、私の推測です。
確認ツールの動作について、manを確認したり、libvirt.org内を検索したのですが、情報は得られませんでした。
とはいえ、libvirt公式のvalidation tool ですし、ツールを実行するだけで問題解決のヒントを得られるので気軽に実行してみるのが良いと思います。

確認ツールの実行

確認ツールを実行します。
私の環境 (Fedora32) の出力も貼っておきます。
いくつかWARNがあるものの、FAILが一つもないので問題無さそうです。
※実際、KVMの動作確認 (2/2)KVMが動作していることを私の環境で検証済みです

virt-host-validate qemu
  # QEMU: Checking for hardware virtualization             : PASS
  # QEMU: Checking if device /dev/kvm exists               : PASS
  # QEMU: Checking if device /dev/kvm is accessible        : PASS
  # QEMU: Checking if device /dev/vhost-net exists         : PASS
  # QEMU: Checking if device /dev/net/tun exists           : PASS
  # QEMU: Checking for cgroup 'cpu' controller support     : WARN (Enable 'cpu' in kernel Kconfig file or mount/enable cgroup controller in your system)
  # QEMU: Checking for cgroup 'cpuacct' controller support : PASS
  # QEMU: Checking for cgroup 'cpuset' controller support  : WARN (Enable 'cpuset' in kernel Kconfig file or mount/enable cgroup controller in your system)
  # QEMU: Checking for cgroup 'memory' controller support  : PASS
  # QEMU: Checking for cgroup 'devices' controller support : WARN (Enable 'devices' in kernel Kconfig file or mount/enable cgroup controller in your system)
  # QEMU: Checking for cgroup 'blkio' controller support   : WARN (Enable 'blkio' in kernel Kconfig file or mount/enable cgroup controller in your system)
  # QEMU: Checking for device assignment IOMMU support     : PASS
  # QEMU: Checking if IOMMU is enabled by kernel           : PASS

WARNの解消については現在のところ特に調べていませんが、libvirt.orgでcgroupを検索するとcgroupに関するページがヒットしました。
ここを読めば、何かがわかるかもしれません。

CPUが仮想化支援機能をサポートしていること

確認手順

以下のコマンドを実行して文字列が表示されれば、CPUが仮想化支援機能をサポートしているので問題ありません。
VMXはIntel VT-x、SVMAMD-V と紐づく言葉であり、どちらもCPUの仮想化支援機能を表す言葉です。

egrep -o '(vmx|svm)' /proc/cpuinfo
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx
# vmx

対処法

もし上記フラグが出てこなかった場合、以下も併せてご確認ください。

上記を確認してもおかしいと感じた場合は、後述のBIOSが仮想化支援機能を無効化していないことをご確認ください。
または、CPUの型番から仮想化支援機能のサポート有無を改めてご確認ください。

BIOSが仮想化支援機能を無効化していないこと

確認手順

以下のコマンドを実行し、何も表示されなければ問題ありません。
もし、"KVM: disabled by BIOS" というメッセージが出てきた場合は、BIOSによってCPUの仮想化支援機能が無効化されている可能性があります。

dmesg | grep -i kvm

対処法

BIOS設定画面を表示し、仮想化支援機能を有効化する必要があります。

BIOS設定画面の表示方法、そもそも設定変更できるのか否かは、BIOSのマニュアルをご確認ください。

ちなみに、私が使っているNUC10BIOSの場合は設定項目自体ありませんでしたが、特に仮想化支援機能は使えていたので問題なしです。

KVMカーネルモジュールがロードされていること

確認手順

以下のコマンドを実行し、kvmとkvm_intel、またはkvmとkvm_amd が表示されれば正常です。
非常にレアケースだと思いますが、何も表示されなかったり、kvmしか表示されない場合は対処が必要な可能性があります。

lsmod | grep kvm
# kvm_intel             319488  0
# kvm                   823296  1 kvm_intel
# irqbypass              16384  1 kvm

対処法

まず、IntelAMDのCPUを使っていない場合には、kvmしか表示されなくても問題ない可能性があります。

IBM POWER8 か IBM POWER9 の場合はこちらをご確認ください。

IBM Zの場合はこちらをご確認ください。

(無いと信じたいですが) IntelAMDのCPUを使っていても表示が想定外になった場合は、手動でのモジュールロードを試してみると良いかもしれません。

まずは設定ファイルを変更せず、起動時のみに影響を与える方法カーネルモジュールをロードしてみます (OSが起動しなくなったら怖いので)。
Intel製ではなくAMD製CPUを利用している場合は、kvm_intelkvm_amdに読み替えてください

sudo modprobe kvm_intel

もう一度確認してみます。

lsmod | grep kvm

この方法で解決できる場合、OS起動時にモジュールを自動的にロードするよう設定すれば解決できるはずです。
これは未検証なのですが、設定ファイル (/etc/modules-load.d/kvm.confなど) に以下のように記述してOSを再起動すれば、恐らく直ります。 (情報元:man modules-loaded.d)。

kvm_intel

再起動後にもう一度確認し、カーネルモジュールがロードできていれば対処完了です。

蛇足ですが、正常に動作している環境においてもVMを起動していなければsudo modprobe -r kvm_intelkvm_intelカーネルモジュールを除外すれば、不具合の発生している状況を再現できます。

/dev/kvm の権限が正しいこと

確認手順

公式にも切り分け方法として書いてあったので、稀にこの不具合にあたるケースがあるようです。

参考情報として、KVMを問題なく利用できている私の環境における出力を貼ります。
/dev/kvmkvmグループから参照できるようになっており、kvmグループにはqemuユーザーが所属する構成でした (Fedora32の場合)。
/dev/kvmQEMUKVMに連携する時に利用されるKVMのインターフェース部分なので、qemuユーザーがアクセスできれば問題ないと考えています。

ls -l /dev/kvm
# crw-rw-rw-. 1 root kvm 10, 232 Nov 23 19:27 /dev/kvm
#
grep kvm /etc/group
# kvm:x:36:qemu

なお、kvmカーネルモジュールがロードされていない場合は、/dev/kvm がそもそも生成していませんでした。
/dev/kvmが存在しない場合には、KVMカーネルモジュールがロードされていることも改めてご確認ください。

対処法

軽く検索したところ、Ubuntu 18.04 ではこのトラブルが発生するケースがあるようです。
2つの情報ソースを確認したところそれぞれ別の対象法を取っていますが、最終的にqemuユーザーが/dev/kvm にアクセスできるよう構成することで不具合を回避しているようです。

バイスファイルの場合はOS再起動するたびに権限やオーナー設定がリセットされるので、chownやchmodで変更しても一時的にしか対処できないようです。
ちなみにFedoraの場合は、KVM公式ページに書いてあるようにudevで/dev/kvmの権限を変更していました。
以下の出力のうち、1行目が該当します。
記載内容の意味は、man udev を読めば確認できます。

grep -r kvm /etc/udev/rules.d/ /usr/lib/udev/rules.d
# /usr/lib/udev/rules.d/50-udev-default.rules:KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"
# /usr/lib/udev/rules.d/50-udev-default.rules:KERNEL=="udmabuf", GROUP="kvm"

言い換えると、/usr/lib/udev/rules.d/50-udev-default.rulesに以下の行を追記すれば直ると思われます。

KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"
KERNEL=="udmabuf", GROUP="kvm"

(参考) qemu:///system と qemu:///session の違い

libvirtには、connectionというオプションがあります。
libvirtを使う際、connectionURIを指定することで、制御対象の仮想化製品を示す必要があります。

QEMU+KVM (またはQEMU単体) を操作する場合は、以下のいずれかのURIを使用します

  • qemu:///system
  • qemu:///session

本記事ではqemu:///systemを使う前提で手順を紹介しました。
qemu:///systemは公式で推奨されていますし、こちらのほうがトラブルを踏みにくいと感じたためです。

次のセクションで両者の違いを簡単に紹介します。

両者の違いを紹介するにあたり、以下の記事を参考にしました。

qemu:///system

rootユーザによって起動されたlibvirtdデーモンを介してVMを操作します。
libvirtがシステムのリソースにアクセスするために必要な権限を一通り持つため、基本的には何でもできます。

ちなみに、qemu:///systemは、rootユーザーのユーザーセッションでもあります。
すなわち、sudo virsh --connect qemu:///session listと仮に実行したとしても、sudo virsh listと同じ意味になります。
このことからもqemu:///systemは特権と同等であるということがわかります。

qemu:///systemを利用するには、必要な設定が2つあります。

1. libvirtグループへの所属

libvirtはPolkitと連携しています。
Polkitは、非特権のプロセスが特権を持つプロセスにアクセスする仕組みを提供するツールキットです。
Polkitで適切なポリシーを定めて適用することで、セキュリティリスクを最小限に抑えつつ、非特権プロセスから特権プロセスへのアクセス権限を付与できます。
sudo に似たような仕組みと思えば理解しやすいと思います。

普段virshやVirtual Machine ManagerによってVMを作る際、一般ユーザーで作業します。
つまり、上記操作によって発行されるのは非特権プロセスです。
一方で、qemu:///systemというURIでアクセスするのは、rootユーザーによって起動されたlibvirtd (即ち特権プロセス) ですので、Polkitの影響を受けます。
具体的には、virshやVirtual Machine Managerを操作するたびに毎回パスワードを求められるようになります。
これは非常に面倒です。

幸い、こちらのブログに記載されているように回避策はあります。
VMを操作する一般ユーザーから以下のコマンドを発行し、libvirtグループに所属させることでパスワードを求められなくなります。
これに相当するPolkitのルールは、/usr/share/polkit-1/rules.d/50-libvirt.rulesに記載がありました。

sudo usermod --append --groups libvirt $(whoami)

この操作は初回のみ実施すれば、その後意識する必要はなくなります。

2. イメージファイルのパーミッション

2つ目の注意点として、イメージファイルのパーミッションが挙げられます。
VMをインストールする際、ISOファイルが必要となります。
ISOファイルの多くは、インターネットからダウンロードすることで入手します。

例えば、ダウンロードしたISOファイルを$HOME/Downloadsに格納したとします。
このディレクトリは、通常ダウンロードしたユーザーにしかアクセスできません。

一方で、QEMU/KVMVMを作成する際にISOファイルをマウントするよう操作した場合、このISOファイルにqemuユーザーが読み取りアクセスします。
面倒なことに、この時ISOファイルが先ほどの$HOME/Downloadsに置かれていると、パーミッションエラーによってVMの起動に失敗してしまいます。

同じことがVMのディスクイメージファイル (qcow2) についても当てはまります。

対策としては、イメージファイルへのアクセス権限をqemuユーザーに持たせる ことが必要です。
具体的な実装例は、pool 作成の事前準備を参照してください。

別の回避策として、FAT32でマウントしたUSBにISOやqcow2ファイルを配置する方法も提案されていました。
FAT32にはパーミッションの概念がないらしいので、ここに配置するだけでパーミッションを意識する必要がなくなるという原理です。

qemu:///session

現在のログインユーザーによって起動されたlibvirtdデーモンを介してVMを操作します。
libvirtdは非特権プロセスですので、Polkit周りの意識は不要です。
また、未検証ですがqemuユーザー周りの権限で悩むこともなくなるようです。

しかしながら、libvirt公式のFAQでは、基本的にqemu:///sessionの利用を推奨していません。
なぜなら、qemu:///sessionを使った場合、特権を必要とする操作ができなくなってしまうためです。

具体的にできなくなることはこちらのブログに譲ります。
必要な設定を入れれば qemu:///system でも問題なく動作するため、基本的にはqemu:///sessionを利用するメリットは少ないと考えます。
しかしながら、セキュリティなどの都合でqemu:///sessionを使う必要がある場合は、本記事の--connect qemu:///system--connect qemu:///sessionに読み替えればそのまま使えます。

(参考) libvirt (virsh) の用語

virshコマンドを使うにあたり、知っておくと便利な用語を紹介します。
libvirt公式のTerminology and goalsを元にしています。

用語 意味
node 物理サーバ
hypervisor ハイパーバイザー役のソフトウェア。本記事の文脈ではQEMU+KVMのこと。
domain 仮想マシンやコンテナ
pool VMのディスク(qcow2)、ISOファイルを格納先を示す設定オブジェクト

特にdomainはvirshのサブコマンドで出てくるので、知っておくと便利です。

また、domainやpoolの状態遷移図もざっくり頭に入れておくとvirshを理解しやすくなります。
公式の図が非常にわかりやすいです。

domain_state
引用元:libvirt.org: States that a guest domain can be in

特に、以下の用語を抑えておくことがvirshを理解する上で重要となります。

用語 意味
define XMLファイルを生成し、libvirt管理下にする
undefine XMLファイルを削除し、libvirt管理から外す
destroy domainの強制終了 (= SIGKILL)、またはpoolの停止
shutdown domainの停止 (VM上でshutdown実行)
start domain/pool の起動

(参考) 仮想NICの設定変更

デフォルトの設定では、defaultという仮想NICが設定されています。
このインターフェースは、VirtualBox でいうNATとホストオンリーに近い性質です。

VMからホスト外部と通信するときは、ホストのIPアドレスにNATされます (≒NAT)。
ただし、ホスト-VM間、VM同士の通信も可能です (≒ホストオンリー)。

仮想NICは、以下のコマンドで一覧表示できます。

virsh net-list
# Name      State    Autostart   Persistent
# --------------------------------------------
 # default   active   yes         yes

仮想NICの設定は、以下のコマンドで表示・編集できます。

virsh net-edit default
# <network>
#   <name>default</name>
#   <uuid>b130cf72-a5eb-4414-9fd8-7d1182f2b50b</uuid>
#   <forward mode='nat'/>
#   <bridge name='virbr0' stp='on' delay='0'/>
#   <mac address='52:54:00:96:e6:67'/>
#   <ip address='192.168.122.1' netmask='255.255.255.0'>
#     <dhcp>
#       <range start='192.168.122.2' end='192.168.122.254'/>
#     </dhcp>
#   </ip>
# </network>

この先はお好みですが、私の環境では上記 virsh net-edit コマンドから、以下の設定のみ変更しました。
これにより、192.168.122.2〜192.168.122.100は静的なIPアドレスアサインできるようになります。

 <range start='192.168.122.101' end='192.168.122.254'/>

変更した場合、設定を反映するためにNICを再起動します。

virsh net-destroy default
virsh net-start default

(参考) おすすめの動画 / 記事

前の記事にも貼りましたが、オススメの動画を紹介させてください。
内容は英語でArch Linuxをベースとした解説ですが、テンポ良く進むので眠くならずに見れると思います。
紹介されている内容は、本記事とほぼ同様です。

(本記事を書き上げて2ヶ月後に以下の動画を見つけました。もっと早く観ていれば私も楽にKVMを理解できたと思うと悔やまれます...。そのぐらい良い動画です)

動画とブログはどちらも同じ作者によるものです。

ブログはこちら:Linux Hypervisor Setup (libvirt/qemu/kvm)

まとめ

本記事では、QEMU+KVMのインストール方法、libvirt CLI (virsh, virt-install) によるVMの作成、KVMの動作確認の手順を紹介しました。

QEMUlibvirtのインストールコマンドはほんの数行です。
ただ、KVMベースのVMが動作するための条件は複数あり、条件を満たすための初期設定やトラブル切り分けは長く、複雑です。

Linux PC 構築関連リンク集

endy-tech.hatenablog.jp

次の記事

libvirtベースのGUIの一つであるCockpitのインストール方法と画面構成について紹介します。
Cockpit は機能拡充中のステータスであるものの、使い勝手がよいのでオススメできます。

endy-tech.hatenablog.jp

デスクトップ環境がある場合は、Virtual Machine Managerも多機能でオススメです。
virshと遜色ない機能性を誇ります。

endy-tech.hatenablog.jp

VM作成/削除、CMROM挿入、起動順序設定などの基本操作のまとめは、以下の記事を参照ください。
CLI/GUIの両方についてまとめてあります。

endy-tech.hatenablog.jp

QEMU、KVM、libvirtの基礎知識まとめ

linux-kvm-logo
引用元: linux-kvm.org

はじめに

LinuxVMを作るにあたり、KVM (Kernel-based Virtual Machine) を使うことにしました。
※使い始めた理由については、#(参考) KVMを使い始めた理由に書きました

KVMを使ってみると、初期設定時に以下のようなもやもやに当たりました。

  • 導入すべきパッケージがよくわからない (必須のもの、任意のもの、いくつかの選択肢から選ぶものが混在している)
  • KVMの動作要件であるVT-x/AMD-Vが何なのかわからずもやもやする
  • KVM周りのコンポーネントが色々あるが、それぞれ何をしているのかわからずもやもやする

本記事は、KVMの導入や使い方紹介に先立って上記の理解を深め、多少なりとももやもやを晴らすことを目的としています。
他記事と比較して、わかりやすさと網羅性を重視して書きましたので、ぜひご覧いただけると嬉しいです。

具体的には、以下を紹介します。

  • KVM仮想化の全体像 (ハードウェア,KVM,QEMU,UI)
  • KVMQEMUの役割の違い
  • KVMQEMUを操作する主なUI (libvirt, Virtual Machine Manager, Cockpit, 他)

KVMの具体的な導入手順、VMの作り方などについては、後続の記事で紹介します。

記事の信頼性について

本記事でまとめた内容は、大半が他のブログや連載記事、Wikipediaを情報ソースとしています。
KVMQEMUを含む各種OSSの公式ドキュメントももちろん確認したのですが、情報が足りない部分が多かったので非公式の記事で補完しました。
従って、情報の正確性については100%ではありません。

本来であれば500ページを超える専門書ソースコードを読み込んで正確に理解することが理想ですが、残念ながらスキルと時間が足りません。
限られた時間の中でKVMを動かすのに必要な理解を得るために、今回はこのような形とさせていただきました。

最後に、本記事に記載した内容は可能な範囲で実機検証済みであり、他の記事やブログでも同様な内容で多く取り上げられていることは申し添えておきます。

広義のKVMと狭義のKVM

広義では、仮想化ソフトウェア (Emulator) を指してKVMと呼ぶことがあります。
内部的には仮想CPU、仮想メモリ、仮想I/Oデバイスを構成し、ホストとは別のOSを起動することで仮想マシンを実現しています。
言い換えると、仮想マシンにおけるCPU処理、メモリ読み書き、ディスク/ネットワークIOは仮想化ソフトウェアの働きによって、物理CPUへの命令、物理メモリ読み書き、物理ディスク/ネットワークI/Oに変換されています。

ただ厳密に言うと、上記のような仮想化はQEMU (アプリケーション) とKVM (カーネルモジュール) の組み合わせによって実現しています。
狭義のKVMは、kvm.ko と呼ばれるLinuxカーネルモジュールを指し、QEMUを含みません。

以降、本ブログではカーネルモジュールとしての狭義のKVMKVMと呼び、QEMUとは明確に区別することにします。

KVM + QEMU 仮想化の全体像

図は、Wikipediaの画像を元にしています。

kvm-diagram_modified

上図の (1)〜(3) について、それらの機能や連携内容を順に紹介していきます。

(1) QEMU (エミュレータ)

QEMUの機能

QEMUは、仮想マシンのエミュレーションを行います。
エミュレーションの対象は、 CPU、メモリ、I/Oデバイスに大別されます。
更に、I/Oデバイスについてはより細かく細分化されます。

具体的なエミュレーション対象のデバイスとしては、主に以下が挙げられます。

  • CPU
  • メモリ
  • I/Oデバイス
    • ハードディスク
    • CD / ISOイメージ
    • ネットワーク
    • ディスプレイ
    • サウンド
    • キーボード
    • マウス

上記リストは、QEMU System Emulation User's Guide、またはman qemu-system-x86_64 でキーワード検索することで洗い出しました。

QEMU = プロセス

QEMUは、Linux上でqemu-system-x86_64 というコマンドで起動され、通常のプロセスとして動作します。
コマンドの x86_64 の部分は、エミュレーションしたいCPUのアーキテクチャによって変わりますが、KVMを使いたい場合は基本的に x86_64 になります。
後述するように、KVMの動作要件である仮想化支援機能は、現時点では x86 アーキテクチャのCPUのみに対応する技術であるためです。

QEMU のインストール方法

Fedoraの場合、以下のコマンドでKVMと連携可能なQEMUをインストールできます。

sudo dnf install qemu-kvm

参考までに、dnf info qemu-kvmの出力を抜粋しました。
qemu-kvmはメタパッケージと呼ばれ、インストールしたシステムがKVMを実行するために必要なQEMUパッケージをインストールしてくれるものです。
多くの場合は、qemu-system-x86がインストールされます。

This is a meta-package that provides a qemu-system-<arch> package 
for native architectures where kvm can be enabled. 
For example, in an x86 system, this will install qemu-system-x86

KVM = QEMUアクセラレータ

QEMUは、単体で仮想マシンの作成・起動・管理を一通り対応できます。
しかしQEMU単体で使うと、仮想マシンの動作は非常に遅くなってしまいます。
QEMUKVMと組み合わせて使うことで、高速に動作するようになります。

KVM仮想マシンを立てると、裏では qemu-system-x86_64 -accel kvm ... というコマンドが実行されます。
つまり、QEMUKVMアクセラレータに指定して実行します。
言い換えると、KVMQEMUのバックエンドと連携して動作し、QEMUが効率的に動作するために一部のバックエンド機能を支援したり代替している と私は理解しています。
KVMが具体的にどのように動くかについては、#(2) KVM (仮想化支援機能との連携) にて概要のみ紹介します。

(参考) QEMU単体とQEMU+KVMの速度比較

2012年の情報ですが、QEMU単体構成とQEMU+KVM構成でパフォーマンスを比較した動画が上がっています。
動画の左側に表示されている「KVM」がQEMU+KVM構成、右側に表示されている「TCG」がQEMU単体構成を表しています。
この動画の環境では、アプリケーションの起動時間が6倍、アニメーションのFPS (1秒あたりのコマ数) にも大きな開きが出ていました 。
TCG という用語については、#TCG (Tiny Code Generator)で補足します

参考URL (QEMUKVMの関係)

下記サイトがよく整理されていて、非常に参考になりました。

TCG (Tiny Code Generator)

TCG (Tiny Code Generator)QEMUコンポーネントの一つで、CPU仮想化を実現するためのものです。
アクセラレータを指定せずにQEMUを実行すると、デフォルトで qemu-system-x86_64 コマンドに -accel tcg がセットされます。

TCGBinary Translation (BT) と呼ばれる技術を使っています。
Binary Translation とは、仮想CPUで処理される命令をハイパーバイザーのソフトウェア処理によって一部書き換えてから物理CPUに渡す機能です。

基本的には高速なKVMを利用するので、TCGの出番はありません。
ただ、KVMを利用するにも条件があります (CPUが仮想化支援機能をサポートしていることと、ホストマシンでKVMカーネルモジュールがロードされていること)。
これらの条件を満たさなかった場合、 qemu-system-x86_64 -accel kvm ... コマンドを発行しても、デフォルトのTCGにフォールバックされます。
このフォールバックの挙動は、 man qemu-system-x86_64-accel オプションの説明からもわかります。

# -accel name[,prop=value[,...]]
This is used to enable an accelerator. 
Depending on the target architecture, 
kvm, xen, hax, hvf, whpx or tcg can be available. 
By default, tcg is used. 
If there is more than one accelerator specified, 
the next one is used
if the previous one fails to initialize.

稀なことですが、KVM利用に失敗してフォールバックされていた場合、「意図せずTCGを利用している」といった状況になる可能性もあります。

(2) KVM (仮想化支援機能との連携)

KVMの機能

KVMは、Linuxカーネルがハイパーバイザとして動作するために必要な機能を提供します。

ただし、KVM自身はエミュレーションを行いません。
QEMU仮想マシンのエミュレーションを行い、KVMは仮想ハードウェアの処理と物理ハードウェアの処理の仲介を行います。

KVMの主な機能は以下です。

KVMの最も重要な機能は、CPUがサポートする仮想化支援機能 (Intel VT-x、またはAMD AMD-V)をQEMUに対して提供することです。
上記の仮想化支援機能はKVMの基本機能でもあり、動作要件でもあります (※)
(※) 例外として、IBM POWERIBM Z 上でもKVMを動作させることは可能ですが、本記事の解説の対象外としています

KVM = カーネルモジュール

KVMは kvm.ko というカーネルモジュールとしてLinux に組み込まれています。

このことはコマンドでも確認できます。
kvmで始まる行がkvmカーネルモジュールをロードしていることを表しています。
同じ行の右側にkvm_intelと書かれているのは、kvmカーネルモジュールがkvm_intelカーネルモジュールに利用されていることを表しています。

lsmod | grep kvm

# kvm_intel             319488  0
# kvm                   823296  1 kvm_intel
# irqbypass              16384  1 kvm

インストール方法

KVMLinuxに組み込まれているので、追加のインストールは不要です。

ただし、LinuxホストのCPUがVT-x、またはAMD-VをサポートしていることがKVMの動作要件となります。

(3) 仮想マシンのドライバ

仮想マシンのドライバには、私の知る限り2パターンあります。

  1. 通常のベアメタルサーバと同様、OSやカーネルに付属する汎用的なドライバを利用するパターン
  2. 準仮想化ドライバ (virtio) を使うパターン

ここで主に触れたいのは、2つ目のvirtioです。

(参考) 準仮想化

準仮想化 (Paravirtualization) とは、仮想化用にチューニングしたOSを仮想マシンとして起動することで、仮想化に特化した機能を仮想マシンに実装する手法です。
具体的にはHypercall (仮想マシンカーネルからホストマシンハイパーバイザーへ直接出す命令) の実装が挙げられます。
準仮想化によって性能や機能性の面でメリットが得られることもありますが、OSに手を入れることで互換性の問題が発生したり、実装が複雑になりうるのが弱点です。

対義語は完全仮想化 (Full Virtualization) であり、ベアメタルと全く同じOSで仮想化を実現する手法です。
少なくともvirtioの存在を無視すれば、QEMU単体やQEMU+KVMは完全仮想化に該当します。

virtio

virtioは、仮想I/Oデバイス (ディスク、ネットワーク、サウンド、ディスプレイ、キーボード、マウスなど) の準仮想化ドライバ機能を提供するAPI群です。

virtioは仕様ソースコードが公開されています。
様々な仮想化製品やハードウェアがある中で、virtioのように統一されたインターフェースを提供することで、仮想化アプリケーション開発者の負担を減らすことができます。

また準仮想化のメリットとして、特にvirtioの場合は性能の向上も挙げられます。
細かいアーキテクチャは理解できていないのですが、実際に汎用的なネットワークインターフェースカードのドライバとvirtioで性能比較し、virtioの方が良い性能を得られたという報告があります (参考1) (参考2)

Hybrid Virtualization

KVMの仮想化支援機能が提供する動作モードの切り替え (VM Entry, VM Exit)は、CPUリソースを多く消費します。
ここにvirtioを組み合わせると、動作モードの切り替わり回数が抑制されて、処理効率が向上するとのことです

このように、QEMU+KVMの完全仮想化の仕組みに、virtioの準仮想化ドライバを組み合わせた仮想化をHybrid Virtualization と呼び、仮想化支援機能を更に高速化させる手段として紹介されています。

QEMU+KVMの仮想化は、Hybrid Virtualization の定義に該当します。

virtio のインストール方法

virtioは、Linuxカーネルに同梱されているようです。

ただWindowsゲスト用のvirtio については同梱されない場合があるようなので、個別にホスト側にインストールが必要なようです。
参考情報として、Fedoraにおけるインストール手順を載せておきます。

sudo wget https://fedorapeople.org/groups/virt/virtio-win/virtio-win.repo \
-O /etc/yum.repos.d/virtio-win.repo

sudo dnf install virtio-win

余談ですが、Windowsゲスト用のvirtioは、ホスト側にインストールして終わりではありません。
上記コマンドは、virtioドライバのインストーラを含むisoファイルをホストに配置するのみです。
実際にvirtioドライバをWindowsゲストにインストールして使用するには、isoファイルをWindowsゲストにマウントして、ゲスト上でインストール操作を行う必要があります。
詳細な手順は、10 Easy Steps To Install Windows Server in Linux KVMというブログに記載があります。
こちらのブログの手順は、私も手元のWindows10評価版で試して動作確認しました。
Windows10評価版は、Microsoft社公式ページよりWindowsのリンクを選択した先からダウンロードできます。

他のディストリビューションでのインストール方法も探せば見つかると思いますが、パッケージが配布されていない場合はFedoraで配布しているISOファイルを直接ディレクトリに配置しても良いようです

参考サイト (virtio)

virtioの概要としては、以下がわかりやすかったです。

参考サイト (仮想化技術全般)

QEMU の操作方法

これまでの解説からすると、QEMUがフロントエンドとしてコマンドラインインターフェース (qemu-system-x86_64) とエミュレーション機能を提供し、裏でKVMアクセラレータとして動作する という理解になります。
上記で間違いはないのですが、実際のユースケースではqemuコマンドをユーザーが直接実行することはほぼありません。

QEMUlibvirt経由で操作することが多い

実際には、 libvirtベースのアプリケーションを介して仮想マシンの作成、変更、監視、停止、削除、移行などを行うことがほとんどです。
例えば、Virtual Machine Manager (virt-manager) はQEMU+KVM を操作できるGUIプログラムですが、裏ではlibvirtが提供するAPIを介してQEMUコマンドを発行しています。

具体例として、Virtual Machine Manager でVMを起動した時の ps コマンドの出力は、以下のようになっています。

/usr/bin/qemu-system-x86_64 \
-name guest=fedora_cinnamon,debug-threads=on \
-S \
-object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-1-fedora_cinnamon/master-key.aes \
-blockdev {"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"} \
-blockdev {"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"} \
-blockdev {"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/fedora_cinnamon_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"} \
-blockdev {"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"} \
-machine pc-q35-4.2,accel=kvm,usb=off,vmport=off,dump-guest-core=off,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format \
-cpu Skylake-Client-IBRS,ss=on,vmx=on,pdcm=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,ibpb=on,amd-ssbd=on,rdctl-no=on,ibrs-all=on,skip-l1dfl-vmentry=on,mds-no=on,hle=off,rtm=off \
-m 6144 \
-overcommit mem-lock=off \
-smp 7,sockets=7,cores=1,threads=1 \
-uuid ef88cdc5-8105-448f-b249-97adbe58206a \
-no-user-config \
-nodefaults \
-chardev socket,id=charmonitor,fd=37,server,nowait \
-mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=utc,driftfix=slew \
-global kvm-pit.lost_tick_policy=delay \
-no-hpet \
-no-shutdown \
-global ICH9-LPC.disable_s3=1 \
-global ICH9-LPC.disable_s4=1 \
-boot strict=on \
-device pcie-root-port,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x2 \
-device pcie-root-port,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 \
-device pcie-root-port,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 \
-device pcie-root-port,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 \
-device pcie-root-port,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 \
-device pcie-root-port,port=0x15,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x5 \
-device pcie-root-port,port=0x16,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x6 \
-device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 \
-device virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 \
-blockdev {"driver":"file","filename":"/home/shared/kvm_volumes/fedora_cinnamon.qcow2","node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"} \
-blockdev {"node-name":"libvirt-2-format","read-only":false,"driver":"qcow2","file":"libvirt-2-storage","backing":null} \
-device virtio-blk-pci,scsi=off,bus=pci.4,addr=0x0,drive=libvirt-2-format,id=virtio-disk0,bootindex=1 \
-device ide-cd,bus=ide.0,id=sata0-0-0 \
-netdev tap,fd=39,id=hostnet0,vhost=on,vhostfd=40 \
-device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:00:83:41,bus=pci.1,addr=0x0 \
-chardev pty,id=charserial0 \
-device isa-serial,chardev=charserial0,id=serial0 \
-chardev socket,id=charchannel0,fd=41,server,nowait \
-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 \
-chardev spicevmc,id=charchannel1,name=vdagent \
-device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=com.redhat.spice.0 \
-device usb-tablet,id=input0,bus=usb.0,port=1 \
-spice port=5900,addr=127.0.0.1,disable-ticketing,image-compression=off,seamless-migration=on \
-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pcie.0,addr=0x1 \
-device ich9-intel-hda,id=sound0,bus=pcie.0,addr=0x1b \
-device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 \
-chardev spicevmc,id=charredir0,name=usbredir \
-device usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 \
-chardev spicevmc,id=charredir1,name=usbredir \
-device usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 \
-device virtio-balloon-pci,id=balloon0,bus=pci.5,addr=0x0 \
-object rng-random,id=objrng0,filename=/dev/urandom \
-device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.6,addr=0x0 \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on

この圧倒的なオプションの長さからも察しがつくように、実際の場面ではQEMUコマンドの直接実行をすることはそうそうありません。
多くの場合はもっと使いやすい別のツールを使うことになります。

libvirt とは

libvirtは、仮想化アプリケーションやハイパーバイザを操作するための抽象化レイヤーを提供するソフトウェア群です。

主に、以下の3つの機能を持ちます

機能名 詳細
ライブラリ
デーモン
  • libvirtd デーモン
  • socketを開き、APIアクセスを待ち受ける
  • 通信を受けることでデーモンが自動起動する
    (systemctl status libvirtd のTriggeredBy行より)
  • libvirtd.socketを開くために、libvirtd自動起動は必要
CLI

XMLで構成管理する

libvirt では、仮想マシンの構成情報 (仮想マシン名や仮想CPUコア数など) をXMLファイルに保存して管理します。
CUIGUIで設定するだけでなく、XMLを直接編集することでもVMの構成を変更することができます。

libvirt を利用している製品

libvirt を介して仮想化環境を便利に管理している製品をざっくり紹介します。
詳細な機能や使い方などは、別記事にてそのうち紹介できればと思います。

CLI管理ツール

CLI管理したい場合はvirsh, virt-install, virt-cloneを主として、お好みでvirt-top, guestfishなどを利用します。

CLIツールは、基本的にVM周りの操作をスクリプト化して効率化するときに使う印象です。
CLIツールは指定するオプションが多いこともあり、普段遣いでVMを操作する場合は、GUIの方が結果として早く操作できると思います。

インストールコマンドは以下のようになります。

sudo dnf install libvirt virt-install virt-top libguestfs-tools

virsh は、libvirtの依存関係であるlibvirt-clientに同梱されます。
virt-clonevirt-installに同梱されます。
guestfishは、libguestfs-toolsに含まれます。

virshvirt-installについては、次の記事で使い方を紹介します。

GUI管理ツール (OSS)

GUIで管理したい場合は、Virtual Machine ManagerCockpit を使います。

QEMU+KVMを実行するマシンにデスクトップ環境があればVirtual Machine Manager が利用可能ですが、無いならばWEBベースのCockpit になります。
もちろん、デスクトップ環境があってもCockpitは利用できます。

特にRHELを利用している方は、今後RedHat社としてCockpit を推奨とする動きになっているので、基本的にはCockpit 一択になると思います。
ただし2020年現在、Cockpit と Virtual Machine Manager の間には機能差があるので、利用する機能によってはVirtual Machine Manager や、CLIの出番が来る可能性もあります。

Virtual Machine Manager (virt-manager) のインストールコマンドは以下のようになります。

sudo dnf install virt-manager

Cockpit そのものはFedoraには元々同梱されていますが、CockpitでKVMを操作するために追加でcockpit-machinesのインストールが必要です。
cockpit-machinesをインストールするとcockpitに「Virtual Machine」タブが追加され、仮想マシンを管理できるようになります。

sudo dnf install cockpit-machines

(参考) Virtual Machine Viewer / Remote Viewer

Virtual Machine Viewer (virt-viewer) は、ローカルホストで動作しているVMにコンソール接続するためのツールです。
libvirtでリモートのサーバに接続 (--connect) している場合は、結果的にリモートサーバに接続することもあります。

Remote Viewer (remote-viewer) は、リモートで動作しているマシンにSPICE、VNCなどのプロトコルでコンソール接続するためのツールです。
宛先にlocalhostを指定すればローカルのVMにコンソール接続することもできますが、その用途であればVirtual Machine Viewerの方が若干便利です。
ローカルでVMを起動している場合も、Cockpitをお使いの方であれば導入推奨です。

いずれもGUIアプリケーションであるため、Linux上で利用する場合はデスクトップ環境かWindow Managerが必要です。
MacWindowsからRemote Viewerを使う構成であれば、特に動作要件はありません。

Linux版は以下のコマンドでインストールします。

sudo dnf install virt-viewer
sudo dnf install remote-viewer

Windows版は、https://virt-manager.org/download/からインストールできます。
ページ上にはvirt-viewerと表記されていますが、MSIでインストールするとRemote Viewerがインストールされます。

Macの場合は非公式ですが、brewコマンドでインストールできるようです (Qiita - virt-managerをMacBookにインストール)。

GUI管理ツール (基本有償)

その他のGUI管理の選択肢として、有償製品とそのアップストリームのOSSもあります。
安定版を利用するにはお金がかかりますが、可用性やセキュリティを担保する機能性は非常に高い...と思われます (まだ使ったことがないです)。

具体的な製品名を挙げるとProxmoxRedHat Virtualization (RHV。oVirtのダウンストリーム)Oracle Linux Virtualization Manager (oVirtベース) が有償製品として挙げられます。
一方で無償の製品としては、Proxmox (無償版) と oVirt が挙げられます。

これらの製品はいずれも仮想化技術としてKVMを利用しており、バックエンドAPIとしてlibvirtを利用しています。

インストール手順は複雑になるので、本記事では割愛させていただきます。

(参考) KVMを使い始めた理由

LinuxにもVirtualBoxはあります。
検証用途でVMを立てたい場合は、VirtualBoxでも十分です。

今回、慣れているVirtualBoxではなく敢えてKVM+QEMU に挑んだ理由は、VMware vSphereの代替品としても注目されるProxmox、RHV、Oracle Linux Virtualization ManagerがKVMを利用していると知ったためです。
また、こちらのRedHat社の資料を読み、RHVの定価はvSphereよりも安く見えるといった部分にも興味を持ちました。
※上記資料にも記載されている通りあくまで定価ベースで机上で計算した値なので、導入構成や価格交渉を反映した最終的な金額はまた変わると思いますが...

仮想化製品としては最有力な vSpehereの (安価かもしれない) 代替手段を知っておきたい というのが、私にとっては KVM+QEMU を勉強する原動力になりました。

(参考) おすすめの動画 / 記事

この記事を書いた後にわかりやすい解説を見つけたので、紹介させてください。
内容は英語でArch Linuxをベースとした解説ですが、テンポ良く進むので眠くならずに見れると思います。

動画とブログはどちらも同じ作者によるものです。

ブログはこちら:Linux Hypervisor Setup (libvirt/qemu/kvm)

まとめ

本記事では、KVMのインストールやセットアップに関連する部分を中心に周辺知識を整理しました。
KVM仮想化の基本として覚えるべき要素は3つです。

要素 詳細
QEMU
  • 仮想ハードウェアのエミュレーションを行う
  • 通常プロセスとして存在する
  • KVM
  • CPU仮想化支援機能などを提供する
  • virtio ドライバと相性が良く、QEMUと組み合わせることでVMがより軽快に動作できるようにする
  • カーネルモジュールとしてLinuxに同梱されている
  • libvirt
  • QEMUを初めとして、いくつかの仮想化製品の操作を抽象化するAPIを提供する
  • virshvirt-installなどのCLIvirt-managerなどのGUIのバックエンド
  • デーモンやコマンドラインとして存在する
  • 何も知らない状態でKVMを触り始めて、いざトラブルが発生すると (私のように) 苦労します。。
    公式の情報ソースのないカジュアルなまとめとなってしまいましたが、本記事がこれからKVMを始める方にとって少しでもお役に立てれば嬉しいです。

    Linux PC 構築関連リンク集

    endy-tech.hatenablog.jp

    次の記事

    KVMのインストール手順、libvirt CLI (virsh, virt-install) の初期設定とVM作成手順を紹介します。

    endy-tech.hatenablog.jp

    Tilix の紹介|Linux用ターミナルエミュレーター

    tilix_window
    左が bashtop、右上がhtop、右下がcmatrix -a の出力
    画像クリックで拡大可能

    お伝えしたいこと

    ウィンドウ分割を初めとした便利な機能を持つターミナルエミュレーターが欲しくなったので、Tilix を導入しました。

    本記事では Tilix を選んだ理由、インストール手順、トラブルの回避、お気に入りのカスタマイズを紹介したいと思います。

    特に以下の内容はTilix以外のターミナルエミュレーターにも応用可能ですので、興味のある部分はぜひ読んでみてください。

    • gtk.cssによる見た目のカスタマイズ
    • ls の色にカラースキームが反映されない不具合回避
    • カラースキームNordのダウンロードと適用
    • Quakeモードと通常モードの併用
    • ショートカットキーのカスタマイズ
    • 設定のバックアップ・リストア

    Tilix を選んだ理由

    目立ったバグがない が一番大きな理由です。
    例えばTerminator はブロードキャスト機能がうまく動きません (ブロードキャスト対象が多くなると、正しく複製されなくなる)。
    またTerminatorとGuake は Ctrl+Shift+F によるターミナルの文字列検索がまともに機能しませんでした (検索してもヒットしない)。
    その点、Tilix はどちらも問題なく動いています。
    ※2020年10月時点の情報です

    次に、欲しい機能を持っている ことが挙げられます。
    ちなみに、機能面ではTerminator とGuakeも概ね要件を満たしています。

    • タブ
    • ターミナル分割 (同一タブ内で画面を縦横に分割する機能 ≒ TMUX)
    • ターミナルの表示/非表示の切り替えのショートカット (≒ Quake機能)
    • コマンドブロードキャスト (Guakeは2020/10時点で非対応)
    • コピペ時の確認ウィンドウ (≒ Teraterm)
    • ショートカットキーのカスタマイズ

    インストール手順

    公式手順に従い、以下のコマンドを実行します。

    sudo dnf install tilix
    

    太すぎるタブバーを狭くする

    好みの差が出そうですが、私としてはタブが太すぎると感じたので変更します。
    StackOverflow で議論されていたスタイルシートを参考に、アレンジしました。

    詳細な原理は、(参考) GTKのCSS編集のやり方で紹介します。

    変更前後の比較

    左が変更前、右が変更後

    変更方法

    ~/.config/gtk3.0/gtk.css に以下のように記載することで修正可能です。

    .tilix-background tab, .tilix-background button {
      padding: 0px;
      min-height: 0px;
    }
    
    .tilix-background tab button image {
      padding-right: 1px;
    }
    

    ls コマンドの色がおかしい問題の修正

    Tilix で ls --color コマンドを実行すると、デフォルトでディレクトリは青く表示されます。
    この色はTilix の Color palette が反映されてほしいのですが、 (Tilixではなく) Linux の設定ファイルの記述上、Tilixの設定が反映されず、常に暗い青で表現されてしまいます。

    ここではその挙動を回避し、ディレクトリの色もカスタマイズできるように変更します。

    詳細な原理は、(参考) DIR_COLORSの仕組みで紹介します。

    変更前、変更後

    ls-beforels-after
    左が変更前、右が変更後

    修正方法

    /etc/DIR_COLORS~/.dir_colors にコピーします。
    ターミナルを再起動すれば反映されます。

    cp -p /etc/DIR_COLORS ~/.dir_colors
    

    カラースキームの追加

    Tilix のデフォルトのカラースキームは選択肢が少なめです。
    ただTilix 公式サイトに記載があるとおり、特定のディレクトリにjsonファイルを配置することでカラースキームを追加できます。

    今回は目に優しくてカッコイイNordを追加してみましたので、その手順を共有します。

    ちなみに、本文トップの画像がNord適用後です。
    右上の htop コマンドの出力がNordのカラースキームを反映した配色になっています。
    青系をベースとして、緑や赤も彩度が抑えられており、落ち着いて集中できそうな色合いです。

    NordはTilix 以外にも多数のTerminal Emulator (Terminator, ConEmu => Cmder)、エディタ (Atom, VS Code, vim)、Linux (dircolors) にも対応しています。
    気になる方は下記公式サイトのリンクからダウンロードください!
    本当におすすめです。

    www.nordtheme.com

    Nordの追加

    まず、GitHubから nord.json をダウンロードします。

    github.com

    ダウンロードした nord.json を以下のどちらかのディレクトリに配置します。

    • /usr/share/tilix/schemes → 全ユーザーに反映
    • ~/.config/tilix/schemes/ → 今のユーザーのみに反映

    後はTilix の設定画面を開き、カラースキームからNord を選択するのみです。
    具体的な手順は後述しますが、 Preferences > (プロファイル名) > Colorタブ > Color Scheme から Nord を選択すれば反映されます。

    その他のカラースキーム

    Tilix 公式サイトにもリンクが貼られていますが、以下に多数公開されていました。

    その他お気に入りのカスタマイズ

    Tilix を開き、右上の ボタンから Preferences を選択することで、各種設定が可能です。
    以下に私のお気に入り設定を書き出しますので、よろしければ参考にしてみてください。

    Global

    赤枠の部分を変更しました。

    tilix-settings-global

    1. Ctrl + マウスホイール で拡大・縮小
    2. タイトル部分をCtrl + クリック でタイトル名変更 (暴発防止のため)
    3. 新規セッション追加時、新しいウィンドウで起動する (後述の通り、Quakeモードと通常モードを併用するための設定。Quakeを利用しない場合はSplit Right や Focus Window でも良い)
    4. 選択したテキストを (Shift+Ctrl+Cを押さなくても) コピーする

    ※他にもAlways use advanced paste dialog のチェックを入れることで、Teratermのようなコピペの確認ウィンドウを出せます (Ctrl+Enterで確定)。今回は有効化しませんでした。

    Appearance

    赤枠の部分を変更しました。

    tilix-settings-appearance

    1. ウィンドウ上部のタイトルを 「Tilix」にする
    2. タブ機能を有効化する (Tilixを再起動することで反映)

    Quake

    特定のショートカットキー (Ctrl+@F12) でターミナルの表示/非表示を行えるようにするため、私はQuakeモードを利用しています。
    これにより、Tilix でもGuake のような使い勝手にできます。

    Quakeで動作させるためのショートカットキーの設定方法は「TilixをQuakeモードで利用する」で紹介します。
    ここでは、Quakeモード実行時の見た目の設定を行います。

    赤枠の部分を変更しました。

    tilix-settings-quake

    1. Quakeモードで起動した時のウィンドウの高さ、幅を100% (最大) に。位置を中央に変更 (※)
    2. Tilix のウィンドウから選択が外れたら、自動的にウィンドウを隠す

    (※) 設定画面では高さを90%までしか設定できない ので、以下のコマンドで設定します。

    # dconf write /com/gexperts/Tilix/quake-height-percent 100 と同義
    gsettings set com.gexperts.Tilix.Settings quake-height-percent 100
    

    後ほど(参考) Quake時のウィンドウサイズを変更するにて、上記Quakeの設定をコマンド一行で場面に応じて切り替える方法も紹介します。

    Shortcuts

    デフォルトから変更したショートカットキーを列挙します。

    Application

    アクション ショートカットキー
    Open preferences Ctrl + ,
    View configured shortcuts Ctrl + .

    Session

    アクション ショートカットキー
    Add terminal automatically Alt + F
    Add terminal down Alt + D
    Add terminal right Alt + R
    Edit the session name Shift + F2
    Resize the terminal down Shift + Alt + Down
    Resize the terminal left Shift + Alt + Left
    Resize the terminal right Shift + Alt + Right
    Resize the terminal up Shift + Alt + Up
    Save the current session disabled (Backspace)

    Terminal

    アクション ショートカットキー
    Advanced paste disabled (Backspace)
    Open file browser Alt + E
    Find next F3
    Find previous Shift + F3
    Maximize Terminal Ctrl + Return
    Page down Shift + Page Down
    Page up Shift + Page Up
    Toggle read only Ctrl + Alt + R
    Reset the terminal disabled (Backspace)
    Reset and clear the terminal Shift + Ctrl + L
    Save terminal contents Shift + Ctrl + S
    Scroll down Shift + Down
    Scroll up Shift + Up

    Profile

    + のアイコンからオリジナルのプロファイルを作成し、GeneralタブとColorタブの以下赤枠部分のみ変更しました。
    カラースキームを Nord に設定して、透明度を少し上げるととってもおしゃれになりますよ。

    tilix-settings-profile-general

    tilix-settings-profile-color

    既定のターミナルを切り替える

    Cinnamon デスクトップの場合、Menu (またはSystem Settings) から Preferred Applications を検索し、Terminal の部分を Tilix に設定します。

    default-terminal

    TilixをQuakeモードで利用する

    やりたいこと

    tilix --quake のように --quake オプションをつけて実行すると、Tilix はQuake モードで起動します。
    デフォルトでは、Quakeモードで起動するとウィンドウの枠を省略したデザインで画面上側に起動します。

    その状態でもう一度 tilix --quake を実行すると、Tilixはバックグラウンドに隠れます。

    ここで、Ctrl+@ というショートカットキーに tilix --quake を割り当てれば、Tilixの表示 / 非表示切り替えボタンになります。
    慣れれば Alt + Tab で切り替えながら作業するより便利なので、私はこの設定としています。

    なお、デフォルトの Ctrl + Alt + T でターミナルを起動するショートカットキーはそのまま残しておきます。
    Tilix の設定のGlobalタブにおいて、New Session = New window と設定してある場合、Ctrl + Alt + T を押下した場合は通常モードでTilix が起動します。

    この構成により、TilixひとつでQuakeモードと通常モードに両対応できるようになります

    設定方法

    Cinnamon デスクトップ環境の場合を例に説明します。

    Menu (または System Settings から) Keyboard と検索し、キーボードの設定画面を開きます。
    Shortcuts のタブへ移動し、ショートカットキーの編集画面に移動します。

    shortcut1

    Name にわかりやすい名称を、Command に tilix --quake と入力し、Add を選択します。

    shortcut2

    最後に、 Ctrl+@ などのショートカットキーを割り当てます。
    Guake を使っていた方は、 F12 の方が馴染みがあるかもしれませんね。

    shortcut3

    繰り返しになりますが、デフォルトの Launch Terminal (Ctrl + Alt + T) に割り当てるショートカットキーは特に弄りません。

    shortcut4

    Tilix の設定のバックアップとリストア

    GitHub Issues で作者が紹介した手順を掲載しています。

    バックアップ手順

    dconf dump コマンドを実行すると、設定情報がテキスト形式で出力されます。
    その内容をリダイレクトして保存します。

    dconf dump /com/gexperts/Tilix/ > tilix.dconf
    

    リストア手順

    dconf load コマンドに dconf dump形式の情報を標準入力から渡すことで、設定情報をリストアできます。

    dconf load /com/gexperts/Tilix/ < tilix.dconf
    

    (参考) dconf、gsettings とは

    Tilix の設定情報は、dconf (設定情報管理データベース) で管理されています。
    Quakeモードの設定をCLIで実施するときに gsettings を利用しましたが、gsettingsdconf のフロントエンドとして動作しています (参考:RedHat社ドキュメント)

    つまり、Tilix の設定管理 (変更・保存・復元) の手段は主に3つあるということです。

    • Tilix GUI から起動する Preferences
    • dconf
    • gsettings

    別サイトによると、gsettings は dconf 以外のラッパーとしても使われることがあるようです。
    興味深いです。

    kokufu.blogspot.com

    (参考) dconf-editor

    dconf には dconf-editor というGUIがあります。
    以下のコマンドでインストールできます。

    sudo dnf install dconf-editor
    

    Menu から dconf editor と検索して起動できます。
    実際に触ってみると、使い勝手はかなり良いです。
    以下にスクリーンショットを貼ります。

    dconf-top

    ↑トップ画面

    dconf-search

    ↑検索ウィンドウから「Tilix」と検索してジャンプできる

    dconf-list

    ↑デフォルト値から変更されたものには鉛筆アイコンがつく

    dconf-read

    ↑設定名をクリックすると詳細情報を確認できる

    (参考) GTKCSS編集のやり方

    Tilixのタブの高さを変更するためにCSSを編集しました。
    CSSのクラス名をどのように調べたのか、気になる方向けに補足します。

    GTKベースのアプリは、GTKインスペクターを利用することでスタイルシートの要素を調べることができます (参考:Gnome Project)。
    ブラウザデバッグを駆使してブログをカスタマイズするのと同じようなイメージです。

    GTKインスペクターは gtk3-devel に付属するため、まずはそれをインストールします。

    ※注意:gtk3-devel は依存パッケージが非常に多いため、Gnomeベースのデスクトップ環境以外を使っている方は、下記コマンドを実行しないほうが良いです。
    私は検証用のVMでこの操作を行いました。

    # debianベースの場合:sudo apt install libgtk-3-dev
    sudo dnf install gtk3-devel
    

    つづいて、Tilixが停止された状態で、Tilix以外のターミナル (Gnome Terminalなど) から 以下のコマンドを実行します。

    GTK_DEBUG=interactive tilix
    

    すると、デバッグ用ウィンドウと共にTilix が起動します。
    後は、以下の手順でブラウザデバッグと同じ要領でCSSの要素を調べます。

    1. デバッグウィンドウの Object タブを開く (赤枠)
    2. 左上の ● のようなアイコンを選択し、Tilix のウィンドウのスタイルを見たい部分をクリックする (赤枠)
    3. ドロップダウンリストを CSS nodes に変更する (赤枠)
    4. クラス名や適用されているスタイルの内容を確認する (ピンク枠)
    5. CSS タブにお試しでスタイルを書いて挙動を確認する
    6. ~/.config/gtk-3.0/gtk.css を編集し、tilix を再起動してスタイルが反映されたことを確認する

    gtk-inspector

    GTKスタイルシートは、Tilix 以外のGTKベースアプリ全てに影響を与えます。
    ここでコツですが、「Tilix」など、可能な限りアプリケーション固有のキーワードを含むクラス名を指定すると、想定外の動きを抑えることができます。
    後は要素名 (notebookなど) クラス名 (.tilix-backgroundなど) をスペース区切りなどで指定し、影響範囲を絞り込んでカスタマイズします。

    私はCSSの経験はほとんどないのですが、以下サイトを参考になんとかできました。

    (参考) DIR_COLORSの仕組み

    Terminal が色を表示する仕組み

    スクリプトを斜め読みしたレベルなので正確ではないかもしれませんが、色が決まるのは概ね以下の流れです。

    • ターミナルエミューレータ起動時にTERM環境変数をセットする
      • Tilixの場合、TERMには xterm-256color がセットされている
      • Tilix で echo $TERM を実行するとわかる
    • ターミナル起動時に、/etc/profile.d/colorls.sh が読み込まれる
      • ~/.dir_colors~/.dircolors~/.dir_colors.$TERM~/.dircolors.$TERM が読み込まれる
      • 上記ファイルが見つからなかった場合、/etc/DIR_COLORS.$TERM が読み込まれる
      • 上記ファイルが見つからなかった場合、/etc/DIR_COLORS.256color が読み込まれる
      • 上記ファイルが見つからなかった場合、 /etc/DIR_COLORS が読み込まれる
        • デフォルトでは /etc/DIR_COLORS.256color が読み込まれる
        • 上記手順で ~/.dir_colors を作成した場合は、代わりに ~/.dir_colors が読み込まれる (中身は /etc/DIR_COLORS と同じ)
      • dircolors コマンドにより、LS_COLORS 環境変数にカラーコードがセットされる
    • ls --color コマンド実行時、LS_COLORS に従ってエスケープシーケンスで色情報を付与して結果を出力する
    • Tilix はエスケープシーケンスを読み込み、Color Scheme に沿って色を変換して描画する

    最後の工程でようやくTilix が登場しました。
    これはいくつか実験した上での想像なのですが、Tilix は内部的にカラーコードの対応表を持っているようです。
    特定のエスケープシーケンス (例えば、青 = \e[34m) を受け取ったら、TilixはColor Shemeのjsonファイルに記述された対応するHTMLカラーコード (例えば 青 = #81A1C1) で描画している、と私は理解しています。

    Tilix の Color Palette

    GitHub Issues でのやり取りによると、以下のColor Palette に各色名称ごとに2色ずつ定義されていますが、「左側が通常の色」、「右側が明るい色 (the one on the right is light color)」を表しているとのことです。
    つまり、「青」を例に図解するとこのようになります。

    tilix-color-explained

    一方で、デフォルトで読み込まれる /etc/DIR_COLORS.256color はどうなっているかと言うと...

    grep DIR /etc/DIR_COLORS.256color 
    # DIR 38;5;33  # directory
    

    ディレクトリの表示色が 38;5;33 となっています。
    38;5; で始まる色は88/256色対応のカラーコードであり、 通常のBlue (34) や Light Blue (94) とは異なる色です。
    Tilix のColor Palette には 38;5;33 は存在しないので、これは変換されずに「そのまま」表示されます。

    一方で、/etc/DIR_COLORS は8/16色対応のカラーコードで記述されており、Tilix のColor Palette の変換テーブルに対応しています。

    grep DIR /etc/DIR_COLORS
    # DIR 01;34    # directory
    

    今回はディレクトリを表す青色に着目しましたが、実行ファイルの緑色など、他にも同様の現象が発生していました。

    こういった事情から、Tilix を使うときは /etc/DIR_COLORS のカラーコードを利用する方が相性が良いようです。
    ※実際に試してみると、Gnome Terminal も /etc/DIR_COLORS を読み込んだ方が良いようでした。他のターミナルエミュレーターも同様な気がします

    ls コマンドの色がおかしい問題の修正において /etc/DIR_COLORS~/.dir_colors にコピーすることで読み込むカラーコードを変更していたのは、こういった背景からでした。

    参考サイト

    Linux のカラーコードについては、以下のサイトが大変参考になりました。
    こちらのサイトに載っているように、 echo -e "Default \e[34mBlue\e[0m" といったコマンドを試しに実行してみると、色の挙動について理解が深まります。

    https://misc.flogisoft.com/bash/tip_colors_and_formatting

    (参考) Quake時のウィンドウサイズを変更する

    先に紹介したカスタマイズでは、Quake時の画面幅・高さ共に100%とし、Ctrl + @ 実行時に画面全体を覆うようにTilix が起動するようにしました。
    しかし、場合によっては画面左半分にブラウザを、画面右半分にTilixを設置したいケースもあると思います。
    Super + → などでTilix のウィンドウを寄せても良いのですが、Ctrl + @ を押すたびに位置がリセットされてしまうので面倒です。

    そこで以下のファイルを作成し、コマンド1つでTilixの設定を切り替えられるようにしました。
    tilixctilixrtilixl を実行することで、「最大化」、「右寄せ」、「左寄せ」を切り替えることができます。

    以下の例では gsettings set を使っていますが、もちろん dconf write を使っても大丈夫です。

    ~/.local/bin/tilixr (画面を右に寄せる。Tilixのウィンドウがフォーカスから外れても最小化しないようにする)

    #!/bin/bash
    
    echo -e 'Aligning Tilix to the right...\n'
    
    gsettings set com.gexperts.Tilix.Settings quake-alignment right
    gsettings set com.gexperts.Tilix.Settings quake-height-percent 100
    gsettings set com.gexperts.Tilix.Settings quake-width-percent 50
    gsettings set com.gexperts.Tilix.Settings quake-hide-lose-focus false
    
    echo Done.
    

    ~/.local/bin/tilixl (画面を左に寄せる。Tilixのウィンドウがフォーカスから外れても最小化しないようにする)

    #!/bin/bash
    
    echo -e 'Aligning Tilix to the left...\n'
    
    gsettings set com.gexperts.Tilix.Settings quake-alignment left
    gsettings set com.gexperts.Tilix.Settings quake-height-percent 100
    gsettings set com.gexperts.Tilix.Settings quake-width-percent 50
    gsettings set com.gexperts.Tilix.Settings quake-hide-lose-focus false
    
    echo Done.
    

    ~/.local/bin/tilixc (画面を最大化する。Tilixのウィンドウがフォーカスから外れたら自動的に最小化する)

    #!/bin/bash
    
    echo -e 'Aligning Tilix to the center...\n'
    
    gsettings set com.gexperts.Tilix.Settings quake-alignment center
    gsettings set com.gexperts.Tilix.Settings quake-height-percent 100
    gsettings set com.gexperts.Tilix.Settings quake-width-percent 100
    gsettings set com.gexperts.Tilix.Settings quake-hide-lose-focus true
    
    echo Done.
    

    ~/.local/bin/tilixt (画面を上に寄せる。Tilixのウィンドウがフォーカスから外れたら自動的に最小化する)

    #!/bin/bash
    
    echo -e 'Aligning Tilix to the top...\n'
    
    gsettings set com.gexperts.Tilix.Settings quake-alignment center
    gsettings set com.gexperts.Tilix.Settings quake-height-percent 30
    gsettings set com.gexperts.Tilix.Settings quake-width-percent 80
    gsettings set com.gexperts.Tilix.Settings quake-hide-lose-focus true
    
    echo Done.
    

    ~/.local/bin/tilixc の状態で tilixrtilixltilixt を実行しても即時反映されない場合は、Super + → やウィンドウのドラッグなどで最大化を解除してから、Ctrl + @ を2回押してQuakeウィンドウを再読込することで反映されます。

    まとめ

    Linux 用の Terminal Emulator として Tilix について諸々紹介しました。
    機能の多さ、バグの少なさという点で、私の中ではTilix が一番好みでした。

    冒頭に記載したとおり、ここに書いた内容のほとんどはTilix 以外のターミナルエミュレーターにも応用可能ですので、ぜひ活用してくださいね。

    Linux Desktop リンク集

    endy-tech.hatenablog.jp

    Linux で音が出ないときの対処法

    speaker-icon

    お伝えしたいこと

    Linux では、しばしば 音が出ない... といったトラブルが発生します。
    原因は非常にたくさんあり、正確に全てを切り分けることは困難を極めます。

    今回は、私が NUC10にFedoraを導入したときに、イヤホンジャックから音が出ず、マイクも使えない問題を解消した 経験を元に、トラブル解消に役に立つ情報を紹介したいと思います (もちろんNUC10以外の方にも役立ちます)。

    トラブルシューティングの記事なので、思考の過程も記載したので記事が長くなっていますが、ご了承ください。。
    ただ、音声周りの問題は根が深いようですので、実際にトラブル踏んでしまった方はこの記事と同様に原因を切り分けて行くのが良いかと思います。

    本記事の解説中に、ALSAPulseAudioといった専門用語を連発します。
    これらについて先に知っておきたい方は、先に(参考) PulseAudioって何?を読んでみてください。

    記事内リンク

    この記事で紹介している解決方法は、以下の2点です。

    マイク・スピーカーなどのハードウェアが認識されないトラブルに対して、snd_hda_intel の modelオプションを設定することで解決する手順は、対策に書いてあります。

    ハードウェアが認識されているが単純に音が出ない場合は、先に音量設定を確認したほうが良いと思います。
    GUIサウンド設定はもちろんのこと、よりデバイス寄りのレイヤーで動いているALSAやPulseAudioの音量設定も確認したほうが良いと思います (特にDebian系の方)。
    ALSAやPulseAudioの音量設定の確認・修正方法については、(参考) その他の不具合原因として考えられるものをご覧ください。

    環境

    項目 詳細
    PCモデル NUC10i5FNH
    コーデックモデル Realtek ALC256
    ディストリビューション Fedora 32 Server
    カーネルバージョン 5.8.10-200

    何が起こったか

    イヤホンマイクを挿しても音が出ません。
    マイクは音を拾っている...と思いきや、これもイヤホンマイクではなくPC本体に内蔵されたマイクが反応していただけでした。
    上記のPC内蔵マイク以外にも、Bluetoothでペアリングしたスピーカーも正しく動作して音を出してくれました。

    つまり、イヤホンジャック周りのスピーカーやマイクだけがまともに動かない状態でした。
    他のハードウェアはうまく動いています。

    結論を言うと、今回のトラブルの原因はLinuxサウンドドライバ (snd_hda_intel) に対する model というオプションの設定不足でした。

    切り分け

    デスクトップのサウンド設定を確認してみる

    Cinnamon Desktop のサウンド設定を開いてみます。
    下図のように右下のスピーカーアイコンから Sound Settings を開きます。
    または、左下のMenu から sound と検索しても見つかります。
    もちろん、system-settings (System Settings) から探しても良いです。

    sound1

    Output のタブ (ヘッドホンやスピーカー) を確認すると、Dummy Output と表示されます。
    経験上、Output可能なデバイスが一つも検出されていないときに Dummy と表示されるようです。
    イヤホンマイクを挿していてもこの表示が出るのですが、本来であれば Headphones とでも出てほしいところです。
    つまり今回のケースでは、スピーカーやヘッドホンなどのデバイスが正しく認識されていないことがわかりました。
    ※更に厳密にいうと、NUC10というPCのイヤホンジャックの先にあるサウンドカードが正しく認識されていません

    sound2

    Input のタブ (マイク) を確認すると、Internal Microphone と表示されています。
    これはイヤホンマイクではなく、PC内蔵のマイク (別のハードウェア) です。
    使っているPCによっては、こちらも Dummy Input と出ると思います。
    今回のケースではイヤホンマイクを挿しているのですが、PC内蔵のマイクしか認識されていないので、ここも何だかおかしいです。

    sound3

    PulseAudioのサウンド設定を見てみる

    pavucontrolのインストール

    PulseAudio のリアルタイムの設定変更は pacmd というコマンドラインツールでも可能なのですが、GUIツールを使ったほうが圧倒的にお手軽でオススメです。
    というわけで、まずはGUIツールを入れます。

    sudo dnf install pavucontrol
    

    この先 pavucontrol ベースで見ていきます。
    対応するpacmdコマンドを知りたい方は、(参考) 回避策をお読みください。

    pavucontrolによる設定確認

    pavucontrolは、デスクトップのMenu から PulseAudio Volume Control を検索して実行するか、pavucontrol コマンドを実行することで起動できます。

    では、pavucontrol を起動し、Configurationタブを開いて設定を確認してみます (CLIでは pacmd list-cards 相当)。
    私の環境では、Analog Stereo Input と出てきました。
    トラブっている環境によっては、 off と出てきます。

    sound3_2

    実は、ここの設定もおかしいです。
    音声の Input (入力) は、マイクなどを表します (デバイスからPCへの音声データ入力、という意味)。
    Input の指定では、マイクから音を拾えますが、スピーカーから音を出すことはありません。
    本来は、ここが Duplex という設定であるべきです。
    Duplex = Input + Output です。音声入力 (マイク) と音声出力 (スピーカー/イヤホン) を両方使いたい場合は、Duplex が適用されている必要があります

    上記画像のプロファイル名をクリックし、Duplex や Inputの部分がどうなっているかを確認してみましょう。

    profile_unavailable

    (Unavailable) と表示されています。。
    Linux Kernel ではデフォルトでjack_detect が有効になっており、イヤホンジャックの抜き挿しを検知できる仕組みになっています。
    ここでUnavailable と表示されているのは、イヤホンジャックに物理的に何も接続されていないか、ドライバの動作不具合などによってスピーカーやヘッドホンが正しく認識されていないためです。
    今回の場合、イヤホンを挿しているにも関わらず (Unavailable) と表示されているので、やはりトラブルが発生しています。

    手動で PulseAudio の Profile を Duplex に変更してみる

    (Unavailable) と表示されたプロファイルも、PulseAudio 起動時にこのプロファイルが自動選択されないだけで、手動で選択することができます。
    というわけで、手動でプロファイルをDuplexに変えてみます。

    sound4

    手動でPulseAudio のプロファイルを Duplex に変更したところ、音声が出るようになりました。

    ↓デスクトップ環境のサウンド設定でも、ヘッドホンがOutputとして正しく認識されています。

    sound6

    ↓ただ残念ながら、Inputのタブではイヤホンマイクは認識されていません。
    今回はPulseAudioのProfileをInputからDuplex (Input+Output) に変えただけなので、Input側が改善していないのは予想通りです。

    sound3

    原因

    ここまでの切り分けで原因がはっきりしてきました。

    • イヤホンジャックにヘッドホンやスピーカーを挿しても、デバイスが正しく認識されていない (何らかの原因でjack_detectがうまく働いていない?)
    • PulseAudio側のProfile自動選択に影響し、本来Duplexが選択されるべきところがInputのみになってしまった
      • Duplexを手動選択することでOutputデバイス (イヤホン) は正しく利用できる状態になった
      • しかし、Inputデバイス (イヤホンマイク) は改善されなかった

    完全に対処するには、「デバイスが正しく認識されていない」状態をどうにかする必要があります。
    「デバイスの認識」と言えばドライバかなと思い調べたところ、今回は運良くヒットしました。
    詳細は次の(参考) カーネルのドキュメント抜粋に譲りますが、要約すると以下のようになります。

    • Linuxサウンドドライバは、サウンドカードがIntel製か他社製かに関わらず必ず snd-hda-intel である
    • HDA (High-Definition Audio) の構成要素は、コントローラチップとコーデックチップである
    • コントローラチップは、多くの場合正しく動作する
    • 一方、 コーデックチップはBIOSが壊れていたり、ベンダー固有の実装が必要だったりの理由で、デフォルトの構成では動作しないことが多い
      • ドライバ関連のトラブルの大半がコレ
    • これらの問題を解消するためには、ドライバーに model というオプションを記載する必要がある
      • model は fixup とも呼ばれます
    • model 名はプリセットされたもの。モデルの選択肢はカーネルバージョンアップのたびに増える (はず)
    • 現在搭載しているコーデックチップのモデルを調査し、動きそうな「モデル」を適用して動かしてみるのが主な切り分け方法
    • 動作するモデルがない場合の選択肢は、主に以下

    そして、私のパソコン (NUC10i5FNH) の場合は、運良く動作するモデルがあった ということになります。
    次のセクションである対策に続きます。

    (参考) カーネルのドキュメント抜粋

    上記のサウンドドライバとモデルの話の情報源を示すため、Linux Kernel Documentation から一部内容を抜粋しました。
    情報ソースが気になる方は、以下をクリックして読んでみてください。
    訳もつけておきました。

    対策

    概要

    対策方法ですが、snd-hda-intel ドライバに model というパラメータを渡すことになります。
    設定ファイルを書いて再起動すれば反映されます。
    再起動後、サウンド設定を開いて問題が解消されたかどうかを確認します (イヤホンマイクが認識され、音が出たりマイクの音に反応していれば成功)。 モデル名を変えつつ何度も試行錯誤します。
    かなり根気のいる作業になります。。。

    とはいえ、私は2候補しか選択肢がなく、2つ目で運良く解決しました。

    以下に詳しい手順を記載します。

    コーデックチップの model を特定する

    grep -i codec /proc/asound/card*/codec#* を実行することで特定できます。

    [stopendy@pc ~]$ grep -i codec /proc/asound/card*/codec#*
    /proc/asound/card0/codec#0:Codec: Realtek ALC256
    /proc/asound/card0/codec#2:Codec: Intel Kabylake HDMI
    [stopendy@pc ~]$ 
    

    私の環境ではコーデックチップが2つあるので、2つ表示されたようです。
    「どちらが目的のコーデックなのか」ですが、正直なところ勘...でしょうか?

    私の場合はイヤホンジャックを直したいので、消去法で ALC256 になります。
    HDMI (画面接続用規格) ではないですからね。
    ちなみにRealtek はハードウェアベンダー名です。

    参考までに、似たような情報を得られるコマンド出力も貼っておきます。
    こちらはハードウェアベンダー名とモデル名が別々に表示されます。

    [stopendy@pc ~]$ cat /sys/class/sound/hwC*D*/vendor_name
    Realtek
    Intel
    [stopendy@pc ~]$ cat /sys/class/sound/hwC*D*/chip_name
    ALC256
    Kabylake HDMI
    [stopendy@pc ~]$ 
    

    さて、モデル名が ざっくり ALC256と判明しました。
    ALC256は、残念ながらドライバに渡せる model オプションとは別の値です
    この文字列をヒントに、適したmodel を手動で試していく必要があるのです。。。

    model 名を探す

    下記URLがモデル名の一覧です。

    https://www.kernel.org/doc/html/latest/sound/hd-audio/models.html

    URLに latest と記載があるとおり、あくまで最新版のカーネルに関するリスト です。
    不安な方は uname -rカーネルバージョンを確認の上、正しいバージョンのドキュメントを参照してください。

    提供されているドキュメントのバージョンはこちらから確認できます。
    URLの中からlatestの部分を環境に合わせたバージョン番号に置き換えてご確認ください。

    さて、今回探したいのは ALC256 なわけですが、alc256 で検索すると以下の2つがヒットします。

    Intel NUCi5FNHASUSではないので不安がよぎりますが、運良く alc256-asus-mic でうまく動作したので、今回はそちらを使います。
    本当に運が良かったです。
    パッチ書いてくれた方、ありがとうございます。

    model オプションを反映する

    Linuxにおいて、ドライバはカーネルモジュールとして実装されるそうです (lsmod | grep -E 'snd_hda_intel|snd-hda-intel' で確認できます)。
    そして、カーネルモジュールにオプションを与えるには、/etc/modprobe.d/*.conf に記述した上でOS再起動してやればOKです。

    構文については man modprobe.d を参照ですが、options modulename option=value といった形式で記載していきます。
    コンフィグファイルは新しいものを作るのが良いと思います。
    新規で作ったことがわかりやすいので。

    ということで、今回は /etc/modprobe.d/stopendy.conf に以下のファイルを作ります。
    (ファイル名は各自変えてくださいね。また、ファイル書き換えにはroot権限が必要です)

    # This file is manually made by stopendy.
    ######################################################
    
    # add an option to specify a codec model to prevent the jack_detect issue
    options snd_hda_intel model=alc256-asus-mic
    

    # で始まる行はコメントなので、省略しても結構です。
    また、model=の後の文字列は環境によって異なるので、先の手順で特定したモデル名で各自置き換えてください (NUC10の方は上記で動くはず!)。

    再起動して設定を反映します。

    reboot
    

    直ったことを確認する

    再起動完了したら、動作確認します。
    OS再起動後でも良いので、ヘッドセットなどをイヤホンジャックに挿しておいてください。
    jack_detection があるので、挿していないと認識されません。

    デスクトップのサウンド設定

    Menuから Sound で検索し、デスクトップ環境のサウンド設定を開きます。

    Input、Output のタブを確認すると、イヤホンマイクがそれぞれの画面で認識されていることがわかります。
    また画像では表現できませんが、実際にこの環境で オンライン飲み会 音声入出力ができることも確認できました。

    sound6

    sound7

    PulseAudioのサウンド設定

    続いて、Menu から PulseAudio Volume Control (pavucontrol) を起動し、Configuration タブを開きます。
    下記画像のとおり、OS起動後に自動で Analog Stereo Duplex が選択されています。
    バイスが正しく認識されているので、Unavailable になったりはしません。

    sound5

    コマンドの場合、pacmd list-cards で確認できます。

    長くなりましたが、ドライバのモデル指定により、今回のイヤホンジャックから音が出ず、マイクも使えない問題が無事解決しました!

    (参考) 回避策

    上記対策が実施できない方向けの回避策です。
    必要な方のみ 以下の手順を実施ください。

    最新のパソコンを導入した場合、残念ながらドライバのモデルが提供されておらず、上記で対応できないケースもあると思います。
    そんな時のために、ワークアラウンドとして デスクトップログイン後に自動でPulseAudioのプロファイルを指定する方法 を紹介します。

    ただこの方法、手動で PulseAudio の Profile を Duplex に変更してみるにも記載があったとおり、完璧ではありません。
    私の環境では、イヤホンジャックに挿したイヤホンから音は出ました。
    ただ、イヤホンマイクは相変わらず認識されないままでした。

    それでもやらないよりはマシなので、新しいmodel が追加されるまでの間、こちらでやり過ごすのも手かなと思います。

    使うコマンド

    pacmd set-card-profile <サウンドカードのIndex番号、またはサウンドカード名> <プロファイル名> です。
    pacmd はPulseAudio の設定を変更するCLIツールです。

    ただ、このコマンドはデスクトップ環境に再ログインするたびに設定が消えてしまいます。
    なので、このコマンドをGUIログインのたびに実行するように設定します。
    Windowsでいうところの「スタートアップ」ですね。
    XDG (X Desktop Group) 互換のデスクトップ環境であれば、~/.config/autostart/*.desktop ファイルに必要な情報を記述すればOKです。

    サウンドカードのIndex番号を調べる

    pacmd list-cards | grep -E 'index:|name:|device.*description|device.vendor.name|device.string' コマンドで確認します。

    以下の出力を例にすると、Indexが0、カード名が alsa_card.pci-0000_00_1f.3 です。
    コマンドにはこれらのどちらかを指定すれば良いのですが、alsa_card.pci-0000_00_1f.3 の方が確実な気がします。
    Index番号は何かのきっかけで変わる可能性があるかも...と思いました。

    [stopendy@pc ~]$ pacmd list-cards | grep -E 'index:|name:|device.*description|device.vendor.name|device.string'
        index: 0
        name: <alsa_card.pci-0000_00_1f.3>
            device.vendor.name = "Intel Corporation"
            device.string = "0"
            device.description = "Built-in Audio"
    [stopendy@pc ~]$ 
    

    指定したいプロファイル名を調べる

    pavucontrol のプロファイル名表示を頼りに探します。
    例えば Analog Stereo Duplex (ちなみにこれはProfile Description) に固定したい場合は、以下のコマンドでプロファイル名を調べられます。

    [stopendy@pc ~]$ pacmd list-cards | grep 'Analog Stereo Duplex'
            output:analog-stereo+input:analog-stereo: Analog Stereo Duplex (priority 6565, available: no)
    [stopendy@pc ~]$ 
    

    上記サンプルでは、 output:analog-stereo+input:analog-stereo がプロファイル名になります。
    長い。

    コマンドを手動実行し、プロファイルを変更してみる

    上記の結果より、今回は以下のコマンドを実行すれば変更できることがわかりました。

    pacmd set-card-profile alsa_card.pci-0000_00_1f.3 output:analog-stereo+input:analog-stereo
    

    PulseAudio Volume Control (pavucontrol)Configuration タブを確認し、コマンド実行によってプロファイルが変わったことを確認できればOKです。

    デスクトップログイン時に自動実行するよう登録する

    まずはCinnamon Desktop におけるやり方から紹介します。
    他の環境でもできるよう、CLIでのやり方も最後に簡単に紹介します。

    左下のMenu から Startup Applications を起動します。
    PulseAudio が自動起動に登録されていました。
    ペンのアイコンから試しに開いてみたのが以下の画像です。
    Startup Delay が 0になっていますね。
    これは、デスクトップログイン直後に即時起動するという意味です。
    ここを1以上にすると、秒単位で実行タイミングを遅延させることができます。

    startup1

    では、先ほど動作確認した PulseAudio のプロファイルをセットするコマンドをスタートアップに登録しましょう。
    + のアイコンからプログラムを追加します。
    そして、以下のように入力します。

    startup2

    項目
    Name Custom_pacmd_set_card_profile
    Command pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo
    Comment Set PulseAudio card profile manually. This should be executed after PulseAudio starts
    Startup delay 1

    Command は環境に合わせて変更してください。
    NameComment はわかりやすいように記載すれば良いと思います。
    Startup delay は、1以上にしてください。PulseAudio 起動よりも後に実行してほしいためです。

    上記の通り登録すると、設定ファイルが以下のパスに生成されます。
    デスクトップ環境に Startup Application 相当の機能がない場合は、以下のファイルを直接作っても同じだと思います。

    [stopendy@pc ~]$ cat ~/.config/autostart/Custom_pacmd_set_card_profile.desktop 
    [Desktop Entry]
    Type=Application
    Exec=pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo
    X-GNOME-Autostart-enabled=true
    NoDisplay=false
    Hidden=false
    Name[en_US]=Custom_pacmd_set_card_profile
    Comment[en_US]=Set PulseAudio card profile manually. This should be executed after PulseAudio starts
    X-GNOME-Autostart-Delay=2
    [stopendy@pc ~]$ 
    

    余談ですが、既存のスタートアップファイルはユーザー個別ではなくシステムワイドな設定として、/etc/xdg/autostart/*.desktop に配置されています。

    設定が完了したら、再ログインの上でPulseAudio Volume Control (pavucontrol)Configuration タブを確認し、Profile が自動設定されていることを確認しましょう。
    CLIの場合は、pacmd list-cards で確認できます。

    (参考) その他の不具合原因として考えられるもの

    バイスは認識されているんだけど、何故か音が出ない。
    デスクトップの音量設定もミュートじゃないのに。

    そういった方はこちらを参考にしてみてください。

    私は今回踏んでいませんが、世の中一般としては以下の切り分けも必要だと言われています。

    • ALSAがミュート、または音量ゼロになっていないか?
    • PulseAudioでミュート、または音量ゼロになっていないか?

    それぞれ確認と修正方法を紹介します。

    ちなみに他の掲示板で「ユーザーを audio,pulse,pulse-access といったグループに所属させないとダメ」といったことが書かれているのを見たことがありますが、少なくとも私が使っているFedora 32 + Cinnamon Desktop では関係ありませんでした。
    私のメインユーザーは上記グループに所属していませんが、全く不具合は起こっていません (追加しても音が出ない問題は解決しませんでした)。

    ALSAの音量確認

    alsamixer コマンドを実行します。
    すると以下の画面に移動します。

    alsamixer_1_master

    左上にPulseAudio と書かれているので、ここを弄るとシステム全体に影響します。
    操作方法は以下の通りです。

    入力キー 意味
    h ヘルプ表示
    w 音量増加
    x 音量減少
    操作対象の音量バーの切り替え
    q 左耳の音量増加
    e 右耳の音量増加
    z 左耳の音量減少
    c 右耳の音量減少
    m ミュート、ミュート解除
    F6s サウンドカードの切り替え
    Esc 画面を閉じる (設定は即時反映のため保存は不要)

    F6キーを押して、サウンドバイスごとの音量も確認します。
    ↑↓キーでHDA Intel PCH を選択し、Enter キーで確定します。

    alsamixer_3_select_sound_card

    alsamixer_4_realtek

    上記に示した画像が正しく動いている構成の例です。

    音量バー、及び音量を表すオレンジ色の数字がゼロや小さい値ではないことを確認してください。音量が小さい場合は↑キーなどで大きくしてみてください。

    また、ミュートになっていないことも確認してください。
    音声バーの下の緑色の「00」の部分が「MM」となっている場合は、mキーでミュートを解除してみてください。
    上記画像で、左から3番目の「S/PDIF」の部分ががミュートになっているのでご参考までに。

    PulseAudio の音量確認

    PulseAudio の設定は PulseAudio Volume Control (pavucontrol) で行うのが楽です。
    PulseAudio Volume Control を起動し、各タブで音量がミュートになっていないか、音量が小さすぎないかを確認します。

    例として、Input (スピーカー) のタブの画像で説明します。
    下記画像の赤枠部分を確認し、画像のようにミュートになっていないことと、音量がゼロではないことを確認してみてください。

    pavu_input

    コマンドの場合は、 pacmd list-sinks でスピーカーなどのOutputタブ相当の情報が、pacmd list-sources でマイクなどのInputタブ相当の情報が確認できます。

    (参考) 切り分けに役立ちそうなコマンドの列挙

    今回私が色々調べた中で役に立ちそうなコマンドをここに書いておきます。
    /proc/sys を含むコマンドはLinuxカーネルaplayALSApacmdはPulseAudioのコマンドです。

    • 認識されているハードウェアのメーカーやモデルなどの情報
      • sudo lspci -v | grep Audio -A10
      • grep -i codec /proc/asound/card*/codec#*
      • cat /sys/class/sound/hwC*D*/vendor_name
      • cat /sys/class/sound/hwC*D*/chip_name
      • cat /sys/class/sound/hwC*D*/modelname
      • aplay -l | grep ^card
    • ALSAの音量、ミュート設定
      • alsamixer
    • PulseAudioの音量、ミュート設定 (sources = input = マイクなど)
      • pacmd list-sources | grep -E 'index:|name:|state:|^\s*volume:|muted:|device.*description|device.vendor.name|device.string|alsa.id'
    • PulseAudioの音量、ミュート設定 (sinks = output = スピーカーなど)
      • pacmd list-sinks | grep -E 'index:|name:|state:|^\s*volume:|muted:|device.*description|device.vendor.name|device.string|alsa.id'
    • PulseAudioのプロファイルの定義が書いてある場所
      • grep 'Analog Stereo Duplex' /usr/share/pulseaudio/alsa-mixer/profile-sets/*

    (参考) PulseAudioって何?

    こちらにわかりやすく説明されています。
    以上!

    mickey-happygolucky.hatenablog.com

    ...なのですが、本文でも超簡単に書いておきます。

    PulseAudio とは、音声系の入出力を集約管理する音声サーバーです。
    ブラウザなどで音楽を聞いているとき、 ブラウザ > PulseAudio > ALSA > カーネル(ドライバ) > ハードウェア (スピーカー、ヘッドホン) に届きます。
    マイクで音を拾う際は逆向きの経路です。マイク > カーネル > ALSA > PulseAudio > 録音ソフトなど ですね。

    ALSAとPulseAudio の関係性は、上記URLでわかりやすく説明されているので良かったら読んでみてください。
    ざっくり、アプリ <--> PulseAudio <--> ALSA <--> カーネル <--> デバイス のパスで音声データがやり取りされており、どこか1箇所でもトラブっていたら音声のトラブルが起きる」といったイメージで良いのかなと思います。
    もちろん構成次第で例外はあると思うのですが、デフォルトの構成であれば上記から大きく外れることはないでしょう。

    上記ブログでは、より具体的に図を交えてわかりやすく解説されています。
    気になる方はぜひ立ち寄ってみてください。
    オススメです。

    まとめ

    今回はコーデックのモデルを設定することで、NUC10で音が出ない問題を解消しました。
    その派生として、音が出ない問題を切り分ける中で得られた知見を共有しました。

    皆さんもトラブった場合は、以下の部分を中心に確認してみると良いと思います。

    • ALSA、PulseAudio それぞれにおいてハードウェアが認識されているか?
    • サウンドドライバのモデルを正しく指定しているか? (デフォルトでは動かないことが多い)
    • サウンドミキサーがミュートになっていないか? (掲示板の事例を見る限り、このケースは最近少ないかも)

    特に、サウンドドライバは、モデルを指定しないと多くの場合動作してくれない というのが衝撃でした。。

    Linux PC構築関連リンク集

    endy-tech.hatenablog.jp