前言

之前主要是因為 Docker Desktop 開始收費 (Docker Subscription Service Agreement | Docker) (Docker CLI 依舊免費 ) 但因為免費條件有點嚴苛,而且通常都是在為了公事使用,為了避免不小心讓公司有意外支出,就開始萌生有沒有更安全的替代解決方案。另外就是 WSL 2 已經很成熟了。

Podman 跟 Docker 目前 (2022/03) 最大的差異應該就是兩者架構不同,Docker 是傳統的 Client-Server 架構它由一個 daemon 來操作所有由 docker cli 產生的 container ,而 Podman 則是不需要 daemon 。這樣可以預防 single point of failure 不會像 docker daemon 一死底下的 container 跟著一起殉情。而多數人在講的 podman 可以 rootless 的優勢則在 docker engine 升級到 20.10 後就也支援 rootless 了,來源在此。

有人針對雙方架構畫了一個很好的圖示

docker_vs_podman 圖片來源: podman_introduction

起步走

=========== ↓↓↓ 25/07/2022 Update ↓↓↓ ==============

目前 Podman 在 Windows 上有更便捷的安裝方式了,整體體驗會更像之前在使用 Docker 的狀況,安裝完成後就可以直接在 terminal / pwsh / cmd 裡面呼叫 podman 操作容器。

目前最新的版本為 Podman 4.1.1 releases 裡面有提供 msi 載點,安裝方式也相當簡單,點個滑鼠就能完事。安裝好之後直接在 pwsh 裡鍵入 podman 就會有相關訊息輸出了。

但整個安裝其實還不算結束,我們需要讓 podman 有一個可以運行的宿主(一個虛擬機器)

沒錯,在 pwsh 鍵入 podman machine init 接著一連串的 output 你會知道他呼叫 WSL 幫你裝了 fedora 然後把 podman 裝在裡面,再產生了一把 SSH Key 方便你連線到該 server 裡面,讓你有個錯覺可以在 windows 環境操作 podman (實際上它依然活在 linux container 裡,你只是不需要先去開起這個容器,再進去容器操作)。機器的名稱預設就叫做 podman-machine-default,這個你用 wsl -l -v 看看目前活著的 distro 就知道。

1
2
3
  NAME                      STATE           VERSION
* Ubuntu                    Stopped         2
  podman-machine-default    Stopped         2

之後就可以不需要再用 podman machine init 來生成環境,只需要呼叫 podman machine start 或是 podman machine stop 來開關機器。

接下來的操作就跟以前在用 Docker 一樣 (或是說就像是在 container 裡面操作 podman 一樣)。

=========== ↑↑↑ ↑↑↑ ===========

官方文件: Install WSL | Microsoft Docs

Windows 使用者請先確保你有安裝 WSL ,若你沒有裝過這個的話初次執行這個指令後就會要求你重啟電腦。

wsl --install => 安裝 WSL (需要用 Admin 權限開啟 terminal)

指令:

將預設的版本變成 version 2

wsl --set-default-version 2

列出線上可以安裝的版本 (基本上可以去 Windows Store 上面看,那邊比較多選擇)

wsl --list --online

安裝指定的版本

wsl --install -d <Distro>

列出目前所安裝的 Linux distros 的狀態

wsl --list --verbose

terminate 指定 Linux distros

wsl -t {dist. name}

安裝並設定完 WSL 之後安裝 Podman 的前置動作就算完成了。

變更安裝位置

基本上 WSL 會將 Linux 所用到的磁碟空間安置在 C槽 (%LOCALAPPDATA%\Packages),若 C槽空間不充裕的話你就會需要用到 WSL 的 export 跟 import 以及 unregister 這三個指令,尤其是 Ubuntu 的版本更新完成後會佔據至少 1.5GB 的空間,若你的 C槽不夠大記得要做以下動作搬移一下 virtual hard disk。

  1. wsl -l -v

先看看本機安裝的 Linux distro 有哪些

  1. wsl --export {Distribution Name} {backup name including path}

第一個參數接你要搬移 virtual hard disk 的 distro name,第二個接輸出的檔名

  1. wsl --unregister {Distro name}

用這個指令將剛剛 export 好的 Distro 給移除,避免等一下 import 時若要用到相同名稱的話不會衝突。

  1. wsl --import {Distro name} {InstallLocation} {TarFileName}

第一個參數放這個 Distro 的名稱,這個名稱若你沒有先移除 (unregister) 先前的 Distro 的話,名字有機會衝突,會要求你填入不同的名稱。第二個參數是你要把 virtual hard disk 放置的位子。第三個就是你在 export 步驟時的完整檔名(含路徑)。

PodMan

這邊先放上官方文件

這邊也用 Ubuntu 來安裝,假設你已經用 WSL2 安裝 Ubuntu 了,這個時候就開啟 Ubuntu

wsl.exe -d Ubuntu

進入 Ubuntu bash 環境後先更新一下套件

Command 1: 更新一下你的系統

1
sudo apt-get update && sudo apt-get upgrade -y

Command 2: 自動抓取你的 OS 資訊

1
source /etc/os-release

Command 3: 註冊新的 apt-get 來源,不然官方預設的位置沒有 podman

1
sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${NAME}_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list"

Command 4: 去把資料來源會用到的 Public Key 抓下來

1
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/x${NAME}_${VERSION_ID}/Release.key -O Release.key

Command 5: 將 Public Key 匯入 apt-get 裡

1
sudo apt-key add - < Release.key

Command 6: 再更新一次套件,並安裝 podman

1
sudo apt-get update -qq && apt-get -qq -y install podman

Command 7

1
sudo mkdir -p /etc/containers

Command 8: 設定一下 config 檔案,讓他知道 image 要去 Docker.io 裡面找

1
echo -e "\[registries.search\]\\nregistries = \['docker.io', 'quay.io'\]" | sudo tee /etc/containers/registries.conf

若你跟我一樣是看 這篇 的話目前 (2022/3/28) 的預期行為是不會自動產生 .config 資料夾以及他底下的設定檔,這一點可以參考官方的討論 Issue 5722

進行到這邊 podman 就算裝好了,我們可以執行以下指令來驗證看看

在 Ubuntu Distro 裡執行 podman run -dt -p 8080:80/tcp docker.io/library/httpd 他就會去 DockerHub 抓 image。

再執行 curl http://localhost:8080或是直接在你的 Windows 環境中用瀏覽器開啟連結(http://localhost:8080),應該會顯示如下內容:

1
<html><body><h1>It works!</h1></body></html>

不過若直接這樣執行 podman 指令的話你輸入 podman info 就可以看到 rootless:false 所以要切換成 rootless:true 的話要先切換使用者不然 WSL 開啟後預設應該會是用 root 這點需特別注意。

在 Ubuntu 中你可以用 su {user name} 來很簡單的切換使用者。

嘗試過簡單的 http server 之後我們來試試用 podman 啟一個 MSSQL 並用 host 來連接。

用 Podman 執行 MSSQL

podman pull mcr.microsoft.com/mssql/server:2019-latest

Podman在運行時會自動幫忙把磁碟掛載起來,所以我們可以利用這點把本機的資料庫檔案使用 -v 參數掛載到容器的路徑裡,讓容器可以存取到本機的資源。要注意的是,存取時容器認的是他自己的位置。

接下來執行指令將 MSSQL for Linux container 啟起來。這幾個參數中 ACCEPT_EULA 跟 SA_PASSWORD 是你一定要特別帶給它的。

podman run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Passw0rd" -e "MSSQL_PID=Express" --name mymssql -p 3341:1433 -v /mnt/c/where/you/mount/data:/var/mssql/data:Z -d mcr.microsoft.com/mssql/server:2019-latest

太棒了! 這樣其實就已經大功告成。

在我們直接在 Host (Windows) 用工具連過去之前我們先進入 container 試試看。

podman exec -it mymssql "bash"

依據預設該 image 會讓我們用預設的使用者 mssql 登入

因為 sqlcmd 工具並沒有加在 container 的 PATH 裡,所以請用完整路徑呼叫,而這邊因為是在 WSL 環境中呼叫,所以 Server 那邊不用特別帶上 PORT (若剛剛有綁定別的 PORT number 的話)

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Passw0rd"

執行候你應該就能夠順利進入 container 的 MSSQL Server。

SELECT host_platform, host_distribution,host_release FROM sys.dm_os_host_info

用好看的介面你會看到如下的畫面:

tsql_check_version

好~我們接下來就可以用 GUI 工具連到這個 DB 裡做操作,不需要這麼克難了。

本文選擇用 DBeaver 而不是 SSMS 做示範,使用 SSMS 的話設定稍有不同。

conn_setting

你可能這樣會說: 這樣是不錯啦,但我有很多資料之前是跑在Windows機器上耶,可以把既有的 DB 掛上去嗎?

恩,當然可以方法很簡單

但從 container 裡面來操作會比較好理解。

這邊我們先假設先前啟動 container 時你的 volume 掛的位置有個 MDF 跟相對應的 Log 檔案。然後我們進入 container 的 sqlcmd 指令模式。

1
2
3
4
USE [master]
GO
CREATE database <DatabaseName> ON (FileName='/{your_path_in_container}/{db_data_name}.mdf'),(FileName='/{your_path_in_container}/{db_log_name}.ldf') FOR ATTACH
GO

這個時候你可以切回 GUI 介面你就能看到你既有的資料庫已經成功地掛載上去了!

想要卸載資料庫的話可以執行

1
EXEC sp_detach_db '{your_db_name}'

若你想透過應用程式連接的話有一個要點需要注意,連線的 IP 位址請先找出身上裝有 Podman 的 Distro 的 IP 而不是 Windows 身上的,這個連線問題同樣適用在 SSMS 身上,所以要用 SSMS 或是應用程式連到 container 內的 MS SQL Server 的話請先在 Distro 內鍵入指令 ifconfig 找到他在用的 IPv4,使用帳號密碼的方式驗證登入,連線字串大概長這樣 Server={ip},{port};User ID={user name};Password={pwd};Initial Catalog={db name};Integrated Security=false;。用這個連線字串你的應用程式應該就可以順利連到 container 內的 DB 了。

這樣你的本地開發環境就算是架設完畢了~

之後你的所有操作就跟本機操作 DB 是一樣的可以無痛轉移又可以順便試試 MSSQL for Linux ❤

Public images

Reference