antony@notes:~/virtualization$ cat "2023-Windows-VMware-IaC-開發及使用手冊-1.md"
2023 Windows & VMware IaC 開發及使用手冊
2023 Windows & VMware IaC 開發及使用手冊
認識 IaC
伺服器環境的手動配置給 IT 專業人員帶來了一些挑戰,例如,由於不斷增加的複雜性和對 IT 基礎架構的相關需求。
Infrastructure as Code,中文翻為 “基礎架構程式碼” ,提供了一種替代方法,將基礎架構的提供、配置與管理方式自動化。
Iac 分為兩種方法,分別是 Declarative (聲明式) 和 Imperative (宣告式)
- 聲明式主要說明基礎系統架構要完成甚麼目標、需要的資源或任何狀態
- 宣告式定義了實現基礎系統架構所需的特定命令,並以正確的順序執行這些命令。
執行它的好處不僅可以降低 Human Error 、縮短建置系統的時間,還可以確保每次都建立出一模一樣的基礎架構。
舉例,在 CNT.2023.v4.5 的套件包裡面的 docker.bat, k8s.bat, dt.bat …等批次檔案,都能快速建立起,對應的基礎架構。
註解:IaC 技術幫我們從落地雲主機自動產生以及複製虛擬主機
- 參考文章連結 1 : 何謂基礎架構程式碼 (IaC)?
- 參考文章連結 2 : What is Infrastructure as Code (IaC)?
- 參考文章連結 3 : Understanding Infrastructure as Code (IaC) in less than 10 minutes
Windows & VMware IaC 平台設計
平台目標
建置分散型 K8S 叢集系統架構,有 1M 2W,或是 3M 3W
重要操作步驟
- K8S 叢集系統準備
- 設計叢集架構 (
mactohost) - 產生虛擬電腦資料夾
- 壓縮虛擬電腦資料夾
- 派送虛擬電腦資料夾
- 解壓縮所有虛擬主機壓縮檔
- 啟動與檢視所有虛擬主機
- 關閉所有虛擬主機
- 備份與還原所有虛擬主機
- 清除所有虛擬主機
實體電腦硬體規格
- 多台實體 Windows 電腦
- 記憶體至少 24 G
- CPU: 4 C / 2 HT
- 須為靜態 IPv4 的 IP 位址
- 每台實體 Windows 10 電腦會分別跑兩台不同的虛擬電腦
虛擬電腦硬體規格
- Alpine Linux 3.17.1 : 6 台
- 記憶體 : 實體 Windows 電腦總記憶體(GB) / 3
- CPU : 2 vCPU
- 網路模式 : bridge
虛擬電腦網路設定
根據叢集的大小來規劃 IP 位址、 Subnetmask 以及 Default Gateway
開始建置 k1 Cluster (1A1M4W)
1. K8S 叢集系統準備
- 確認實體 Windows 10 主機之間可用
SSH連接 測試命令 :> ssh student@<附近好同學的實體 Windows 10 電腦 的 IP 位址>- 如果無法連線,請用系統管理員執行 powershell,並執行以下命令
執行以下命令,檢查 OpenSSH 目前的狀態如果 OpenSSH Server 沒有安裝,命令應返回以下輸出 :
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'Name : OpenSSH.Client~~~~0.0.1.0 State : Installed Name : OpenSSH.Server~~~~0.0.1.0 State : NotPresent - 安裝 OpenSSH Server 命令 :螢幕輸出 :
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0Path : Online : True RestartNeeded : False - 啟動 sshd 服務命令
# Start the sshd service Start-Service sshd # OPTIONAL but recommended: Set-Service -Name sshd -StartupType 'Automatic' # Confirm the Firewall rule is configured. It should be created automatically by setup. Run the following to verify if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) { Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..." New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 } else { Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists." } - 連線附近好同學的實體 Windows 10 電腦 的 IP 位址 測試
> ssh student@<附近好同學的實體 Windows 10 電腦 的 IP 位址> - Install OpenSSH Server on Windows 10 官網連結
- 如果無法連線,請用系統管理員執行 powershell,並執行以下命令
執行以下命令,檢查 OpenSSH 目前的狀態
- 將連接 Windows 的帳號密碼存入
passwd檔案> notepad %USERPROFILE%\CNT.2023.v4.5\K1-1A1M4W\passwd - 將連接 Alpine Linux 的帳號密碼存入
passwd_alp檔案> notepad %USERPROFILE%\CNT.2023.v4.5\K1-1A1M4W\passwd_alp - VMware Player 這軟體一定要做以下設定, 否則 建立 虛擬主機的目錄會殘溜目錄
4-1.
Player>File>Preferences...4-2. In the “Software updates” group > uncheck the “Check for software components as needed” option. - Windows 主機需安裝 7z
- 確認被遠端控制的實體 Windows 主機,開放遠端登入權限 (需用管理員身分打開 CMD 執行以下命令)注意 ! 機碼修改後,需重啟電腦 !
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
2. 設計 k1 叢集架構
設定 k1 叢集架構檔 - mactohost
mactohost在 Windows 中,打開 CMD ,執行以下命令
切換至工作目錄
> cd CNT.2023.v4.5\K1-1A1M4W編輯 mactohost
> notepad k1mactohost檔案內容 :
# Default Cluster
00:00 x1 none
00:01 x2 VMware
00:02 x3 VMware
00:03 a1 admin
00:04 m1 master
00:05 m2 master
00:06 m3 master
00:07 w1 worker
00:08 w2 worker
00:09 w3 worker
# K8S k1 Cluster
10:d2 k1a1 admin k1a1.210.zip k1/alp.k1a1 192.168.39.55
10:d3 k1m1 master k1m1.211.zip k1/alp.k1m1 192.168.39.55
10:d4 k1m2 master
10:d5 k1m3 master
10:d6 k1e1 etcd
10:d7 k1w1 worker k1w1.215.zip k1/alp.k1w1 192.168.39.55
10:d8 k1w2 worker k1w2.216.zip k1/alp.k1w2 192.168.39.55
10:d9 k1w3 worker k1w3.217.zip k1/alp.k1w3 192.168.39.55
10:da k1w4 worker k1w4.218.zip k1/alp.k1w4 192.168.39.55
10:db k1w5 worker欄位說明 :
- 第一欄為 設定 VM 主機 的 Mac Address 最後兩個位元 (byte)
- 用冒號分隔的格式 : 前半部是 k1 = 10, k2 = 20… 依此類推 後半部是 VM 的 IP 位址尾數換算為 16 進位
- 舉例 :
假設現在要設定的是 k1 叢集裡面 IP 位址尾數
.210的 VM, 依照上述規則,得到的答案 :10:d2
- 第二欄為 設定 VM 主機名稱
- 格式 : 叢集名稱 + mactohost 第三欄位的第一個字 + 序號(從 1 開始)
- 第三欄為 各 VM 的角色扮演
- 第四欄為 VM 目錄壓縮檔名
- 格式 : VM 主機名稱 + VM IP 位址的尾數 + 壓縮檔的附檔名 (.zip)
- 第五欄為 VM 存放的目錄名稱
- 格式 :
叢集名稱/alp.主機名稱(alp = Alpine Linux的縮寫)
- 格式 :
- 第六欄為 VM 要分配到哪一台實體電腦的 IP 位址
3. 建立 k1 叢集所有虛擬主機
k1create 程式概述 : 在落地雲主機的 C:\Users\bigred\CNT.2023.v4.5\K3-1A1M4W 目錄下,做出 k1 的資料夾,並在 k1 目錄下建立 6 台虛擬機
:::spoiler 完整程式內容
@echo off
REM 設定 Cluster Name
for /f "tokens=1" %%y in ('dir %CD% /B ^| findstr "mactohost"') do (
set CLUSTERNAME=%%y
)
for /f "tokens=3 delims= " %%z in ('type %CLUSTERNAME:~0,2%mactohost ^| more +11 ^| findstr "#"') do (
set CN=%%z
)
Rem/||(
判斷 Cluster Name 有沒有設定錯誤
- %Variable:~0,2%
是取變數值的前兩個字
- GOTO:eof
在不定義標籤的情況下將控制傳送到當前批次檔的末端,此時,批次檔會自行退出。
)
if NOT %CLUSTERNAME:~0,2% == %CN% (
echo "Cluster Name Error !"
GOTO:eof
)
REM 判斷在當前目錄下是否存在 %CN% (有可能是 k1 或 k2 或是 k*)目錄
if exist %CN%\ (
echo "%CN% Folder existed !"
GOTO:eof
)
REM 設定 VM 可用記憶體範圍
powershell -Command "(Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /3Mb" > max.txt
powershell -Command "(Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /8Mb" > min.txt
set /P MAX=<max.txt
set /P MIN=<min.txt
set RSMMAX='memsize = \"4096\"', 'memsize = \"%MAX%\"'
set RSMMIN='memsize = \"4096\"', 'memsize = \"%MIN%\"'
REM 修改 VM 的 MAC Address 必要設定
set RSADR1='ethernet0.generatedAddressOffset = \"0\"'
set RSADR2='ethernet0.addressType = \"generated\"' , 'ethernet0.addressType = \"static\"'
REM 將 VM 網路模式設為 bridge 橋接模式
set RSTYPE='ethernet0.connectionType = \"nat\"' , 'ethernet0.connectionType = \"bridge\"'
REM 啟動 ALP.K8S 虛擬主機
"C:\Program Files (x86)\VMware\VMware Player\vmrun" start "%USERPROFILE%\CNT.2023.v4.5\ALP.K8S\alpine64.vmwarevm\alpine64.vmx" > nul
timeout /t 60 > nul
Rem/||(
抓 ALP.K8S 虛擬主機的 IP 位址,將命令執行結果重導到 admip.txt 這個檔案中
- 透過 set /P 將 admip.txt 檔案中第一行的內容,設為 admip 變數的值
- 檔案中的第二行以下,包含第二行的內容,都會被丟棄
)
"C:\Program Files (x86)\VMware\VMware Player\vmrun" getGuestIPAddress "%USERPROFILE%\CNT.2023.v4.5\ALP.K8S\alpine64.vmwarevm\alpine64.vmx" > admip.txt
set /P admip=<admip.txt
Rem/||(
上載 mactohosts 至 ALP.K8S 虛擬主機
- 變數 ERRORLEVEL 為上一行命令執行完後回傳的值 ^(exit code^),0 代表執行成功。
- EQU ^(Equal To^)執行數字比較,如果需要字符串比較,使用 == 比較運算符。
- USERPROFILE 變數為顯示當前使用者的家目錄,例如 : C:\USERS\bigred
)
echo y | pscp -pwfile "passwd_alp" ".\%CN%mactohost" bigred@%admip%:/home/bigred/bin/mactohost 2> nul > nul
if %ERRORLEVEL% EQU 0 echo "%CN%mactohost scp ok"
echo y | pscp -pwfile "passwd_alp" bigred@%admip%:/home/bigred/.ssh/* %USERPROFILE%\.ssh\ 2> nul > nul
if %ERRORLEVEL% EQU 0 echo "%admip% .ssh/* scp ok"
del %USERPROFILE%\.ssh\known_hosts 2> nul
del %USERPROFILE%\.ssh\known_hosts.old 2> nul
ssh -o "ConnectTimeout=5" -o "StrictHostKeyChecking=no" bigred@%admip% "sudo apk update; sudo apk upgrade" 2> nul > nul
if %ERRORLEVEL% EQU 0 echo "System upgrade ok"
"C:\Program Files (x86)\VMware\VMware Player\vmrun" stop "%USERPROFILE%\CNT.2023.v4.5\ALP.K8S\alpine64.vmwarevm\alpine64.vmx" > nul
timeout /t 60 > nul
Rem/||(
建立所有 K8S Cluster 的 VM
- SETLOCAL ENABLEDELAYEDEXPANSION 為 啟用變數延遲展開
- 意思是 變數會在執行時才會展開變成它的值,而不是在解析時就變成值
- 要延遲展開的變數格式由 %var% 更改為 !var!
- gc 為 powershell 的命令,用來顯示檔案內容,-replace 參數主要是替換一個文字檔中的字串
- Out-File 將輸出傳到一個檔案, -Encoding 參數將輸出轉換為指定格式
)
setlocal EnableDelayedExpansion
if exist %CN%mactohost (
if not exist %CN%\ (
mkdir %CN% > nul
if %ERRORLEVEL% EQU 0 (
for /f "tokens=1-6 delims= " %%a in ('findstr 120 %CN%mactohost') do (
set x=%%~nxe
set RS='displayName = \"ALP.K8S\"', 'displayName = \"!x!\"'
set y=%%a
set RSMAC='ethernet0.generatedAddress = \"00:0c:29:.*\"' , 'ethernet0.address = \"00:50:56:ab:!y!\"'
mkdir %CN%\!x! > nul
xcopy /E /Y %USERPROFILE%\CNT.2023.v4.5\ALP.K8S %CN%\!x!\ > nul
powershell -Command "(gc %CN%\!x!\alpine64.vmwarevm\alpine64.vmx) -replace "!RS!" -replace "!RSMAC!" -replace "%RSMMAX%" -replace "%RSTYPE%" -replace "%RSADR1%" -replace "%RSADR2%" | Out-File -Encoding "UTF8" vm.temp"
del /Q %CN%\!x!\alpine64.vmwarevm\alpine64.vmx
copy /Y vm.temp %CN%\!x!\alpine64.vmwarevm\alpine64.vmx > nul
if !ERRORLEVEL! EQU 0 echo "%CN%\!x!\ (%MAX%) ok"
)
del *.txt > nul
del vm.temp > nul
)
)
):::
執行建立 K1 叢集命令
在 Windows 工作目錄 CNT.2023.v4.5\K1-1A1M4W 下,執行程式
> create.bat螢幕輸出
"k1mactohost scp ok"
"192.168.179.129 .ssh/* scp ok"
"System upgrade ok"
"k1\alp.k1a1\ (8192) ok"
"k1\alp.k1m1\ (8192) ok"
"k1\alp.k1w1\ (8192) ok"
"k1\alp.k1w2\ (8192) ok"
"k1\alp.k1w3\ (8192) ok"
"k1\alp.k1w4\ (8192) ok"[重要] 根據實體電腦的記憶體來修改 k1create.bat 中 RSMMAX 變數直的大小 [註] 如遇到需要輸入密碼,請參考以下連結 : Windows SSH: Permissions for ‘private-key’ are too open
4. 壓縮 k1 叢集所有虛擬主機
:::spoiler 完整程式內容
@echo off
REM 設定 Cluster Name
for /f "tokens=1" %%y in ('dir /B ^| findstr "mactohost"') do (
set CN=%%y
)
REM 在 mactohost 中抓取壓縮時需要的字串
if exist %CN:~0,2%zip.txt (del %CN:~0,2%zip.txt > nul)
for /f "tokens=3,* delims= " %%a in (%CN:~0,2%mactohost) do echo %%b | findstr zip >> %CN:~0,2%zip.txt
REM 透過 For 迴圈,逐行代變數,壓縮 VM 所在的資料夾
setlocal EnableDelayedExpansion
for /f "tokens=1,2 delims= " %%a in (%CN:~0,2%zip.txt) do (
7z\7z -mx1 a %CN:~0,2%\%%a %%b > nul
if !ERRORLEVEL! EQU 0 (echo "%%a ok")
)
del %CN:~0,2%zip.txt > nul:::
執行壓縮程式
> zip.bat螢幕輸出
"k1a1.50.zip ok"
"k1m1.51.zip ok"
"k1w1.55.zip ok"
"k1w2.56.zip ok"
"k1w3.57.zip ok"
"k1w4.58.zip ok"5. 派送 k1 叢集所有虛擬主機
:::spoiler 完整程式內容
@echo off
for /f "tokens=1" %%y in ('dir /B ^| findstr "mactohost"') do (
set CN=%%y
)
if exist %CN:~0,2%scp.txt (del %CN:~0,2%scp.txt > nul)
for /f "tokens=1* delims= " %%a in (%CN:~0,2%mactohost) do echo %%b | findstr zip >> %CN:~0,2%scp.txt
setlocal EnableDelayedExpansion
for /f "tokens=3,5 delims= " %%a in (%CN:~0,2%scp.txt) do (
echo y | pscp -scp -pwfile passwd "%CN:~0,2%\%%a" bigred@%%b:"%%a" 2> nul > nul
if !ERRORLEVEL! EQU 0 (
echo "%%a to %%b ok"
) else (
echo "%%a to %%b failed"
)
)
del %CN:~0,2%scp.txt > nul:::
執行程式
> scp.bat螢幕輸出
"k1a1.50.zip to 120.96.143.3 ok"
"k1m1.51.zip to 120.96.143.3 ok"
"k1w1.55.zip to 120.96.143.4 ok"
"k1w2.56.zip to 120.96.143.4 ok"
"k1w3.57.zip to 120.96.143.5 ok"
"k1w4.58.zip to 120.96.143.5 ok"6. 解壓縮所有虛擬主機壓縮檔至落地雲主機
:::spoiler 完整程式內容
@echo off
for /f "tokens=1" %%y in ('dir /B ^| findstr "mactohost"') do (
set CN=%%y
)
for /f "skip=12 tokens=4-6 delims= " %%a in (%CN:~0,2%mactohost) do (
for /f "tokens=1 delims= " %%i in ('PsExec.exe -accepteula -nobanner \\%%c -u bigred -p "!QAZ2wsx " -s "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "Test-Path" "-Path" "C:\Users\bigred\%CN:~0,2%\%%~nxb" ^2^>nul') do (
if %%i == True (
psexec -accepteula -nobanner \\%%c -u bigred -p "!QAZ2wsx " -s "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "Remove-Item" "C:\Users\bigred\%CN:~0,2%\%%~nxb" "-Recurse" 2> nul
psexec -accepteula -nobanner \\%%c -u bigred -p "!QAZ2wsx " -s "powershell" "-Command" "Expand-Archive" "-LiteralPath" "C:\Users\bigred\%%a" "-DestinationPath" "C:\Users\bigred" 2> nul
) else (
psexec -accepteula -nobanner \\%%c -u bigred -p "!QAZ2wsx " -s "powershell" "-Command" "Expand-Archive" "-LiteralPath" "C:\Users\bigred\%%a" "-DestinationPath" "C:\Users\bigred" 2> nul
)
)
for /f "tokens=1 delims= " %%i in ('PsExec.exe -accepteula -nobanner \\%%c -u bigred -p "!QAZ2wsx " -s "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "Test-Path" "-Path" "C:\Users\bigred\%CN:~0,2%\%%~nxb" ^2^>nul') do (
if %%i == True (
echo "%%c %CN:~0,2%\%%~nxb unzip ok !"
) else (
echo "%%c %CN:~0,2%\%%~nxb unzip Failed !"
)
)
):::
[註] %%~nxb,在範例中 %%b 為包含目錄的檔案名稱 : k1/alp.k1w1,
%%~nb - 顯示 alp (%%b 的 檔名)
%%~xb - 顯示 .k1w1 ( %%b 的副檔名,包含 .)
執行解壓縮程式
> unzip.bat螢幕輸出
"120.96.143.3 k1\alp.k1a1 unzip ok !"
"120.96.143.3 k1\alp.k1m1 unzip ok !"
"120.96.143.4 k1\alp.k1w1 unzip ok !"
"120.96.143.4 k1\alp.k1w2 unzip ok !"
"120.96.143.5 k1\alp.k1w3 unzip ok !"
"120.96.143.5 k1\alp.k1w4 unzip ok !"7. 啟動與檢視 k1 叢集所有虛擬主機
:::spoiler 完整程式內容
@echo off
for /f "tokens=1" %%y in ('dir /B ^| findstr "mactohost"') do (
set CN=%%y
)
setlocal EnableDelayedExpansion
for /f "skip=12 tokens=4-6 delims= " %%a in (%CN:~0,2%mactohost) do (
psexec \\%%c -accepteula -nobanner -u bigred -p "!QAZ2wsx " -s "C:\Program Files (x86)\VMware\VMware Player\vmrun" "start" "C:\Users\bigred\%CN:~0,2%\%%~nxb\alpine64.vmwarevm\alpine64.vmx" "nogui" 2> nul > nul
if !ERRORLEVEL! EQU 0 (
echo "%CN:~0,2%\%%~nxb started"
) else (
echo "%CN:~0,2%\%%~nxb failed"
)
timeout /t 5 > nul
):::
1. 執行啟動 k1 叢集所有虛擬主機命令
> start.bat螢幕輸出
"k1\alp.k1a1 started"
"k1\alp.k1m1 started"
"k1\alp.k1w1 started"
"k1\alp.k1w2 started"
"k1\alp.k1w3 started"
"k1\alp.k1w4 started"2. 在 Windows 檢測已開啟的虛擬電腦
:::spoiler 完整程式 :
@echo off
for /f "tokens=1" %%y in ('dir /B ^| findstr "mactohost"') do (
set CN=%%y
)
if exist %CN:~0,2%listp.txt (del %CN:~0,2%list.txt > nul)
for /f "tokens=1* delims= " %%a in (%CN:~0,2%mactohost) do echo %%a %%b | findstr zip >> %CN:~0,2%list.txt
for /f "tokens=1,2 delims= " %%a in (%CN:~0,2%list.txt) do (
for /f "tokens=1,2 delims=:" %%i in ("%%a") do (
ping -n 2 "120.96.143.0x%%j" | find "TTL" 2> nul > nul
if errorlevel 1 (
echo "%%b not running"
) else (
ssh -o "ConnectTimeout=5" -o "StrictHostKeyChecking=no" bigred@"120.96.143.0x%%j" "n=$(hostname;hostname -i); echo $n running" 2> nul
)
)
)
del *.txt > nul:::
執行檢測命令
> list.bat螢幕輸出 :
k1a1 120.96.143.50 running
k1m1 120.96.143.51 running
k1w1 120.96.143.55 running
k1w2 120.96.143.56 running
k1w3 120.96.143.57 running
k1w4 120.96.143.58 running8. 關閉 k1 叢集所有虛擬主機
:::spoiler 完整程式內容
@echo off
for /f "tokens=1" %%y in ('dir /B ^| findstr "mactohost"') do (
set CN=%%y
)
if exist %CN:~0,2%stop.txt (del %CN:~0,2%stop.txt > nul)
for /f "tokens=1* delims= " %%a in (%CN:~0,2%mactohost) do echo %%a %%b | findstr zip >> %CN:~0,2%stop.txt
for /f "delims= " %%a in (%CN:~0,2%stop.txt) do (
for /f "tokens=1,2 delims=:" %%i in ("%%a") do (
ping -n 2 "120.96.143.0x%%j" | find "TTL" 2> nul > nul
if errorlevel 1 (
echo "120.96.143.0x%%j not running"
) else (
ssh -o "ConnectTimeout=5" -o "StrictHostKeyChecking=no" bigred@"120.96.143.0x%%j" "sudo poweroff; exit" 2> nul > nul
if ERRORLEVEL 0 echo "120.96.143.0x%%j stoped"
)
)
)
del *.txt > nul:::
執行關機 k1 叢集所有虛擬主機 命令
> stop.bat螢幕輸出
"120.96.143.0x32 stoped"
"120.96.143.0x33 stoped"
"120.96.143.0x37 stoped"
"120.96.143.0x38 stoped"
"120.96.143.0x39 stoped"
"120.96.143.0x3a stoped"9. 備份與還原 k1 叢集所有虛擬主機
:::spoiler 完整程式內容
@echo off
for /f "tokens=1" %%y in ('dir /B ^| findstr "mactohost"') do (
set CN=%%y
)
SET /P an="Would you want to stop all %CN:~0,2% Cluster VM (do/done)"
if %an% == do (
CALL %CN:~0,2%stop.bat
CALL :backup
GOTO:eof
) else (
CALL :backup
GOTO:eof
)
:backup
setlocal EnableDelayedExpansion
for /f "skip=12 tokens=4-6 delims= " %%a in (%CN:~0,2%mactohost) do (
for /f "tokens=1 delims= " %%i in ('PsExec.exe -accepteula -nobanner \\%%c -s "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "Test-Path" "-Path" "C:\Users\bigred\%CN:~0,2%\%%~nxb" ^2^>nul') do (
if %%i == True (
psexec -accepteula -nobanner \\%%c -s "%ProgramFiles%\7-Zip\7z" "-mx1" "a" "C:\Users\bigred\%%a.bak" "C:\Users\bigred\%%b" 2> nul > nul
if !ERRORLEVEL! EQU 0 (
echo "%%a.bak backup ok !"
) else (
echo "%%a.bak backup failed !"
)
) else (
echo "VM folder not found !"
GOTO:eof
)
)
):::
執行備份 k1 叢集所有虛擬主機 命令
> backup.bat螢幕輸出 :
Would you want to stop all k1 Cluster VM (do/done)回答 do –> 會先將 k1 叢集的所有虛擬主機關機後再備份
螢幕輸出 :
"120.96.143.0x32 stoped"
"120.96.143.0x33 stoped"
"120.96.143.0x37 stoped"
"120.96.143.0x38 stoped"
"120.96.143.0x39 stoped"
"120.96.143.0x3a stoped"
"k1a1.50.zip.bak backup ok !"
"k1m1.51.zip.bak backup ok !"
"k1w1.55.zip.bak backup ok !"
"k1w2.56.zip.bak backup ok !"
"k1w3.57.zip.bak backup ok !"
"k1w4.58.zip.bak backup ok !" 回答 done –> 會直接開始備份 k1 叢集所有虛擬主機
螢幕輸出 :
"k1a1.50.zip.bak backup ok !"
"k1m1.51.zip.bak backup ok !"
"k1w1.55.zip.bak backup ok !"
"k1w2.56.zip.bak backup ok !"
"k1w3.57.zip.bak backup ok !"
"k1w4.58.zip.bak backup ok !"[註] 新的備份檔會直接覆蓋掉舊的備份檔
執行還原 k1 叢集所有虛擬主機命令
> restore.bat執行命令後,會先問要不要先關機,要就回答 do 不要就回答 done
螢幕輸出 :
Would you want to stop all k1 Cluster VM (do/done)done
"120.96.143.3 k1\alp.k1a1 restore ok !"
"120.96.143.3 k1\alp.k1m1 restore ok !"
"120.96.143.4 k1\alp.k1w1 restore ok !"
"120.96.143.4 k1\alp.k1w2 restore ok !"
"120.96.143.5 k1\alp.k1w3 restore ok !"
"120.96.143.5 k1\alp.k1w4 restore ok !" 10. 清除 k1 叢集所有虛擬主機
:::spoiler 完整程式內容 :
@echo off
for /f "tokens=1" %%y in ('dir /B ^| findstr "mactohost"') do (
set CN=%%y
)
REM del all include k1* exclude *.bak
SET /P an="Would you want to stop all %CN:~0,2% Cluster VM (do/done)"
if %an% == do (
CALL %CN:~0,2%stop.bat
CALL :del_k8s
GOTO:eof
) else (
CALL :del_k8s
GOTO:eof
)
:del_k8s
if exist ip.txt (del ip.txt)
for /f "skip=12 tokens=6 delims= " %%y in (%CN:~0,2%mactohost) do echo %%y >> ip.txt
setlocal EnableDelayedExpansion
for /f "tokens=1 delims= " %%x in ('type ip.txt ^| sort.exe /unique') do (
psexec -accepteula -nobanner \\%%x -s "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "Remove-Item" "C:\Users\bigred\%CN:~0,2%" "-Recurse" 2> nul
if !ERRORLEVEL! EQU 0 (
echo "%%x %CN:~0,2% folder deleted !"
) else (
echo "%%x %CN:~0,2% folder does not exist !"
)
)
for /f "skip=12 tokens=4-6 delims= " %%a in (%CN:~0,2%mactohost) do (
psexec -accepteula -nobanner \\%%c -s "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "Remove-Item" "C:\Users\bigred\%%a" 2> nul
if !ERRORLEVEL! EQU 0 (
echo "%%c %%a deleted !"
) else (
echo "%%c %%a does not exist !"
)
)
del ip.txt 2> nul > nul
RD /S /Q /S /Q %CN:~0,2% 2> nul
if %ERRORLEVEL% == 0 echo "local %CN:~0,2% folder deleted !":::
執行清除 k1 叢集所有虛擬主機命令
> del.bat執行命令後,會先問要不要先關機,要就回答 do 不要就回答 done
螢幕輸出 :
Would you want to stop all k1 Cluster VM (do/done)done
"120.96.143.3 k1 folder deleted !"
"120.96.143.4 k1 folder deleted !"
"120.96.143.5 k1 folder deleted !"
"120.96.143.3 k1a1.50.zip deleted !"
"120.96.143.3 k1m1.51.zip deleted !"
"120.96.143.4 k1w1.55.zip deleted !"
"120.96.143.4 k1w2.56.zip deleted !"
"120.96.143.5 k1w3.57.zip deleted !"
"120.96.143.5 k1w4.58.zip deleted !"
"local k1 folder deleted !" [註] 會刪除 k1 叢集所有虛擬主機、壓縮檔以及本地的 k1 資料夾,但不包含備份的 (*.bak) 檔
IaC 平臺 開發關鍵技術
技術重點 1 - Windows batch script - 透過 FOR 命令可以將文字檔中的欄位資料取出
:star: 首先要注意 ! 如果要在批次程式中使用 FOR 命令,請指定 %%variable,而不要指定
%variable。變數名稱有大小寫的區分,所以 %i 不同於 %I。
逐行讀取文字檔的 for /F 迴圈
/f ,可以對 for 迴圈傳入的檔案、字串或命令,進行解析,以下為讀取檔案的範例 :
for /f "tokens=3,* delims= " %%a in (k1mactohost) do echo %%b- 概述:逐行讀取
k1mactohost檔案的內容,然後依照分隔符號 (空格) 將檔案內容的值分別設為指定的變數,再將指定的變數內容輸出在螢幕上。 tokens=x,y,m-n用來決定一次要取出幾個欄位,第一個欄位會存放在第一個自動變數,第二個欄位會存放在第二個自動變數裡,依此類推。在範例中為tokens=3,*,代表將第三個欄位的值存放在變數a,其他剩餘欄位的值會放在變數b註:x, x, m, n都為數字,只是m-n是一種特別的表示法,代表一個解析欄位的範圍。例如tokens=2-4就代表取得第2、第 3 與第 4 個欄位的值並分別塞指定的變數裡delims=xxx用來決定欄位的分隔符號,預設為空格與 TAB 符號,並可自訂多個符號。在範例中,將欄位的分隔符號設為空格 註:xxx代表多個字元,如果要同時設定小數點.與逗號,就要輸入delims=.,
練習
有一個文字檔 tip.txt
內容是
10:6e d8a5 120.96.143.22
10:6f d8a6 120.96.143.22寫一隻程式 (tip.bat)用冒號分割顯示以下的結果:
6e
6f答案: $ notepad tip.bat
@echo off
for /f "tokens=1 delims= " %%a in (tip.txt) do echo %%a >> t1.txt
for /f "tokens=2 delims=:" %%b in (t1.txt) do echo %%b$ tip.bat
6e
6f參考文章
如何利用批次檔(Batch)讀取指令執行的結果或文字檔案內容 for 迴圈
技術重點 2 - Windows 遠端啟動 VMware 虛擬電腦
1. 使用 psexec 必須使用此設定
開放遠端登入權限
- 執行 regedit
- 找到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system 新增一個「DWORD 值」,並把它命名為「LocalAccountTokenFilterPolicy」,然後再把他的值設定成「1」。 參考網址 : PsTools 於 Windows 10 的環境設定
2. 下載 psexec.exe 執行檔
$ psexec /accepteula
3. 執行 psexec 命令
啟動虛擬機器
$ psexec \\120.96.143.3 -u bigred -p "!QAZ2wsx " -s -d "C:\Program Files (x86)\VMware\VMware Player\vmrun" "start" "C:\Users\bigred\alp.k1a1\alpine64.vmwarevm\alpine64.vmx" "nogui"-s system account -d 我們連線的實體主機即使斷線,所執行的命令不會因此中斷
4. 如何知道執行 psexec 成功
- 打開工作管理員,確認有沒有以下的顯示

5. 關閉虛擬機器
- 直接下命令
psexec \\120.96.143.5 -u bigred -p "!QAZ2wsx " -s -d "C:\Program Files (x86)\VMware\VMware Player\vmrun" "stop" "C:\Users\bigred\alp.k1w3\alpine64.vmwarevm\alpine64.vmx"- 使用工作管理員在 vmware-vmx.exe 按右鍵結束工作
- 把三個檔案刪掉

參考連結
:book: Everything You Wanted to know About Psexec
技術參考連結
- Compress-Archive
- Understanding Infrastructure as Code (IaC) in less than 10 minutes
- Running Remote Commands
- Using PsExec to Run Commands Remotely
- 延遲變數展開 (EnableDelayedExpansion)
[註] 代表顯示一個空白符號
https://www.w3schools.com/html/html_entities.asp