2026年11月6日

Hyper-V使用Samba的SMB提供VM儲存

前言:

在PVE場景中,或者OpenStack場景中,一般都會這樣描述,運算節點歸運算,儲存節點歸儲存,網路歸網路,這是一般分散式的虛擬化平台作法。
自然的,當使用Microsoft的Hyper-V或者HCS(Host Compute System)時,自然也會想到,可否使用NAS當儲存載體,像PVE這樣,用NFS為基底提供儲存和運算?

細查之後發現,Microsoft提供2個方向,一個是iSCSI,就單純模擬整顆磁碟後給Hyper-V或HCS使用,如果希望使用的是VHD(x)當儲存載體用在儲存主機,Microsoft提供的方式是使用SMB3.0協定。
白話的說,Microsoft可以用網路芳鄰當作Hyper-V/HCS的儲存位置,運行VM。
但當實做使用才發現,這有不少前提,因此有了這篇。

這篇的除錯和設定過程,是由AI協助得出的。

Hyper-V與SMB3:

最初我的想法很單純,不就是網路芳鄰,Samba安裝就打完收工了,結果發現,直接不能用,不是出現resize fail,就是出現create vhdx fail,經過幾天嘗試,始終有問題,看來事情不單純。
經過一系列的查詢後得知,Hyper-V/HCS這類VHD(x)的VM要能以網路芳鄰操作,必須要滿足好幾項條件:
1. 必須是網域:所有操作都要透過網域,因為Hyper-V/HCS的VM的網路芳鄰操作,限定使用電腦帳戶操作,而電腦帳號的授權,是在網域中進行的,因此第一個限定條件是,提供SMB3(網路芳鄰)的檔案伺服器和運算的Hyper-V電腦,都必須加入在同一個網域內,檔案伺服器本身可以是網域主控站(AD-DC),但必須是在網域內。
2. SMB要使用SMB3.0:Windows Server可以參考 Hyper-V 3.0實戰之- Hyper-V 3.0 For SMB 3.0 這篇的描述,簡言之,就是要勾選特定的SMB功能,預設的SMB無法提供Hyper-V VM操作和存取時的必要操作。

簡單的說,Hyper-V/HCS必須要使用SMB3.0的特定功能 + 網域才能正常運作,單純的SMB是不支援的,而這裡所謂單純的SMB,指的很大程度就是Samba。

Samba與Hyper-V VM:

好消息是,Samba在最近幾個月的 4.25 版本中,加入了SMB3.0的功能,雖然還是實驗性質的,但確定可以使用了。
也因為這個實驗性質的功能,我們才知道Hyper-V VM的網路芳鄰需要什麼,需要的是能夠將檔案做全域獨佔存取的能力,也就是說,當Hyper-V在操作檔案時,這個檔案是全域獨占存取,無法被其他存取行為操作的。
它的另一項能力是,有個內部快取,可以讓Windows Server斷線時,短時間內的操作keep在Client端,不會影響到檔案存取,我猜測Samba 4.25實驗性的功能指的應該就是這個,因為它要Client和Server協同作業,而且涉及到斷線後復原的檔案處理,可能跟這個有關,不論如何,至少Samba 4.25版是可以提供SMB3.0能力,讓Hyper-V VM能使用Samba當VM儲存主機,而我會在後面章節描述作法。

Samba Server環境設定:

我這邊File Server是在PVE上面(pve2),pve2本身提供NFS服務,其他PVE都透過NFS連線共用磁碟。
我不希望Samba安裝在pve2上面,這會污染到pve2的系統環境,因此選項有4:
1. Hyper-V Host使用自己的磁碟,這個測試可以,但磁碟用本地磁碟,會讓磁碟難以管理。
2. 用iSCSI,我不想用iSCSI,因為iSCSI會讓儲存變成一個一個raw disk,管理不方便,而且可能會是一次就分配所有磁碟空間,因此不太想用這方案。
3. 用KVM的VM提供Samba服務。
4. 用LXC提供Samba服務。

其實3和4差不多,只是差別在用容器還是用VM,容器的效能比較好,實測起來也是如此,mp(MountPoint)效能比VM的virtiofs效能更好,傳輸直接少一層界面。
我最後KVM和LXC都實做成功了,但主要會以LXC為主,因為LXC的設定可套用在KVM上。

LXC的PVE Host端設定:

LXC在PVE上需要2項設置:
1. 如下修改 /etc/subuid 和 /etc/subgid (KVM不需要這個設定)

Samba AD-DC會需要存取UID和GID 3000000 ~ 4000000,把這批UID和GID對應到網域的電腦帳戶和使用者帳戶,因此在LXC情境中,要先在PVE主機上面先設定這塊UID/GID可被存取。

2. 修改LXC設定,加上 lxc.idmap (KVM不需要這個設定),完整的LXC設定如下:

關鍵是最下面的
lxc.idmap: u 0 100000 65536
lxc.idmap: g 0 100000 65536
lxc.idmap: u 3000000 3000000 1000000
lxc.idmap: g 3000000 3000000 1000000

其實就是跟1對應,指定LXC機器的UID/GID可存取範圍。
這設置的好處是,不需要針對LXC開啟 Privileged (特權容器) 模式,因為Samba AD-DC 實際上需要的只有 UID/GID 存取權,其他沒有特權模式需要的存取設置
。

LXC Samba端設定:

首先,Samba 4.25 只存在 Debian forky 版本,我是安裝 Debian Trixie 之後升級上去的。
Ubuntu 26.04 在另外新增Samba Latest Linux Schools或付費訂閱Samba+是可以安裝的,不過我嘗試 Linux Schools的版本,安裝後systemd沒有samba相關的啟動服務檔案,因此我後來選擇用Debian 13升級。

這邊在開始前,我們要先說明清楚,Samba需要設置成什麼:
1. Samba設定成 AD-DC (網域控制站)
2. Samba自己要成為 DNS Server ,並且要設定上游 DNS Server
3. 要有個獨立網域,建議是在既有Domain設置子Domain,真實Domain 或 內部Domain 都可以,我這邊是用內部Domain
4. 上游DNS要先設定LXC Samba的DNS,按照3設置
5. 要有個符合Windows密碼規則的Administrator密碼

我這裡內部Domain、Host名稱定義如下:
Samba hostname: file-ad.winve.home
Domain(REALM): winve.home
網域: WINVE

上述5點確認後,並且安裝了 Samba 4.25 後,我們就可以開始設定了。
現在Samba 4的 AD-DC 設定已經簡單很多了,有現成的 samba-tool 可以直接產生好設定檔案與相關目錄和設置,但我在 LXC 還視域到點小問題,需要先修改。

1. provision.py 修改
首先,先備份和修改
/usr/lib/python3/dist-packages/samba/netcmd/domain/provision.py


357行改成

skip_sysvolacl=False,   →   skip_sysvolacl=True,


這裡的作用是這樣的,因為我們磁碟都不是本機磁碟,是透過 virtio(KVM) 或 mp(MountPoint)(LXC) 映射到虛擬機內的,因此檔案和目錄權限會需要在 smb.conf 內跳開,不能直接讓它修改檔案和目錄權限操作,所以建立時也是這樣,要讓它略過ACL相關的設置,建置後要改回。

2. 執行 samba-tool
先把 /etc/samba/smb.conf 改名,我的習慣是改成 /etc/samba/smb.conf.default ,然後用 root 執行:
# samba-tool domain provision --server-role=dc --use-rfc2307 --realm=WINVE.HOME --domain=WINVE --adminpass=[Administrator密碼]

順利執行完成後,samba-tool 會建立所需的目錄和 smb.conf。

3. smb.conf 調整
我這邊貼出我的 smb.conf ,並給出要調整的地方
# Global parameters
[global]
interfaces = lo eth0
dns forwarder = 192.168.oo.oo
netbios name = FILE-AD
realm = WINVE.HOME
server role = active directory domain controller
workgroup = WINVE
idmap_ldb:use rfc2307 = yes
persistent handles = yes

[sysvol]
path = /var/lib/samba/sysvol
read only = No
vfs objects = acl_xattr dfs_samba4
acl_xattr:security_acl_name = user.NTACL

[netlogon]
path = /var/lib/samba/sysvol/winve.home/scripts
read only = No
vfs objects = acl_xattr dfs_samba4
acl_xattr:security_acl_name = user.NTACL

[winve-iso]
    path = /home/ooooooo/iso
    browseable = yes
    read only = no
    guest ok = no
    continuous availability = yes
    kernel oplocks = no
    kernel share modes = no
    posix locking = no
    create mask = 0666
    directory mask = 0777
    vfs objects = acl_xattr
    acl_xattr:ignore system acls = yes

[winve-vm]
    path = /home/ooooooo/VMs
    browseable = yes
    read only = no
    guest ok = no
    continuous availability = yes
    kernel oplocks = no
    kernel share modes = no
    posix locking = no
    create mask = 0666
    directory mask = 0777
    vfs objects = acl_xattr
    acl_xattr:ignore system acls = yes
    acl_xattr:security_acl_name = user.NTACL

這裡有2塊設置,
針對SMB3的設定包括:
[global]
persistent handles = yes

各分享的如下:
[Share Name]
continuous availability = yes
kernel oplocks = no
kernel share modes = no
posix locking = no

針對ACL在各分享的設定包括:
[Share Name]
create mask = 0666
directory mask = 0777
vfs objects = acl_xattr
acl_xattr:ignore system acls = yes

這裡針對ACL的設置邏輯是,我沒有使用任何Linux ACL,Linux檔案系統的部份一律把檔案權限設成0666,目錄權限設成0777,而Samba的ACL則透過下面兩條略過。
這裡我簡述網路芳鄰的權限,在網路芳鄰中,權限分2段,網路段透過網路芳鄰限制,本地段透過NTFS檔案系統限制。
對應到Linux Samba,權限同樣分2段,網路段透過Samba限制,本地段透過Linux檔案系統(ext4)限制。
但早期的Linux有個問題,早期Linux沒有NTFS這麼完整的權限控制系統,只有單純的 0777 這樣的權限控制,而 USER 和 GROUP 也沒有 Windows NTFS 這麼詳細,這造成了Samba在設定權限時,Linux本地端權限對應問題,這在 Linux ACL 支援後,已經沒問題了,但一般Linux ACL都是沒開啟的,而我這個Samba就只是專門用於提供Hyper-V/HCS的VM存取使用,加上LXC,因此這邊不處理Linux ACL。

Windows Hyper-V端:

1. 先設定DNS Server
首先要先設定DNS為 Samba 這台電腦的IP

2. 加入網域
系統 -> 加入網域 winve.home
帳號: Administrator
密碼: [Administrator密碼] (samba-tool 執行時帶上的 --adminpass=[Administrator密碼] )

成功加入網域後重新啟動,進入系統。

Hyper-V 指定 \\ooo.ooo.ooo.ooo\winve-vm 當作VM儲存目錄,指定 \\ooo.ooo.ooo.ooo\winve-iso 當作iso的目錄。
應該能正常建立VM,並透過DVD-ROM開機進入Windows安裝程式。

沒有留言: