Sql-Server

在沒有 Internet 的 Windows 伺服器上建構自定義 SQL Server 2017/2019 容器

  • October 12, 2020

我有點進退兩難

我得到了一個執行在 Windows Server 2016 上的虛擬機,並安裝了 Docker Enterprise。我的管理層希望在此 VM 中執行的 Windows 容器上使用帶有 docker 的 SQL Server 2019。這是一個POC項目。VM 沒有任何 Internet 連接,因此我無法從 docker hub 中提取基本映像。我知道有可用的 SQL Server 2017 開發人員版本。可以做些什麼來確保我可以在這種情況下繼續使用容器?特別是當虛擬機沒有任何網際網路連接時?

我嘗試在執行 Windows 10Pro 的本地電腦上下載 SQL Server 2017 Developer 版本,然後將容器映像移動到 VM 上。但是當我嘗試載入容器時,我收到一條錯誤消息,提示“主機作業系統不匹配”。那是當我找到下面的網站時

https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility?tabs=windows-server-2004%2Cwindows-10-2004

請建議我如何在這種情況下創建圖像

在撰寫本文時,SQL Server 2019 Windows 容器仍處於預覽階段。如果您未加入 Early Adopter 計劃,則可以從 Windows Server Core 基礎映像開始創建自定義映像,然後安裝 SQL Server 2019(以及可選的 CU)以創建自定義映像。

建構最容易在具有 Internet 連接的機器上完成,以從公共複製中提取基本 OS 映像。然後,您可以在沒有 Internet 連接的情況下將圖像複製到電腦(或將其推送到本地私有複製器)並從那裡執行它。或者,拉取、保存和載入作業系統映像(步驟 6-8)並在伺服器上執行建構。

以下是執行此操作的一般步驟的範例。我對格式的道歉。我受到挑戰。

  1. 在您的 Windows 機器上創建一個空目錄(例如 C:\dockerfiles)
MKDIR C:\dockerfiles
  1. 在該目錄中創建一個包含以下內容的 dockerfile
#Start with a Windows Server Core base image.
#Note that the image with tag 'latest' is pulled by default, which could be older than the actual host OS version.
#In this case, specify the version-specific to pull a later image compatible with the host OS version.

FROM mcr.microsoft.com/windows/servercore:2004

#Parameters for start.ps1:
ENV sa_password="_" \
    attach_dbs="[]" \
    ACCEPT_EULA="_" \
    sa_password_path="C:\ProgramData\Docker\secrets\sa-password"

#set default shell to PowerShell and set preferences:
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

#set current directory to root (C:\)
WORKDIR /

#copy SQL Server setup folder into build image for installation
COPY setup setup

#run setup to install
RUN  \setup\setup.exe /q /ACTION=Install /INSTANCENAME=MSSQLSERVER /FEATURES=SQLEngine /UPDATEENABLED=0 /SQLSVCACCOUNT='NT AUTHORITY\System' /SQLSYSADMINACCOUNTS='BUILTIN\ADMINISTRATORS' /TCPENABLED=1 /NPENABLED=0 /IACCEPTSQLSERVERLICENSETERMS

#remove setup files
RUN  Remove-Item -Force -Recurse -Path 'setup'

#create empty directory (C:\SqlFiles) for user database files
RUN "mkdir SqlFiles | Out-Null"

#stop SQL Server service, configure TCP/IP, allow SQL authentication, and set default file locations
RUN stop-service MSSQLSERVER ; \
        set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.MSSQLSERVER\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpdynamicports -value '' ; \
        set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.MSSQLSERVER\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpport -value 1433 ; \
        set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.MSSQLSERVER\mssqlserver\' -name LoginMode -value 2 ; \
        set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.MSSQLSERVER\mssqlserver\' -name BackupDirectory -value 'C:\SqlFiles' ; \
        set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.MSSQLSERVER\mssqlserver\' -name DefaultData -value 'C:\SqlFiles' ; \
        set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.MSSQLSERVER\mssqlserver\' -name DefaultLog -value 'C:\SqlFiles' ;

#set command used for container health check status
HEALTHCHECK CMD [ "sqlcmd", "-Q", "SELECT 1;" ]

#copy startup script to image
COPY start.ps1 /

#specify command invoked when container is run from this image
CMD .\start -sa_password $env:sa_password -ACCEPT_EULA $env:ACCEPT_EULA -attach_dbs \"$env:attach_dbs\" -Verbose
  1. 在建構目錄中創建 start.ps1 文件(例如 C:\dockerfiles\start.ps1)。下面是一個類似於我使用的範例腳本。
# The script sets the sa password and start the SQL Service
# Also it attaches additional database from the disk
# The format for attach_dbs

param(
[Parameter(Mandatory=$false)]
[string]$sa_password,

[Parameter(Mandatory=$false)]
[string]$ACCEPT_EULA,

[Parameter(Mandatory=$false)]
[string]$attach_dbs
)


if($ACCEPT_EULA -ne "Y")
{
    Write-Verbose "ERROR: You must accept the End User License Agreement before this container can start."
    Write-Verbose "Set the environment variable ACCEPT_EULA to 'Y' if you accept the agreement."

    exit 1
}

#start the service
Write-Verbose "Starting SQL Server"
Start-Service MSSQLSERVER

if($sa_password -eq "_") {
    if (Test-Path $env:sa_password_path) {
        $sa_password = Get-Content -Raw $secretPath
    }
    else {
        Write-Verbose "WARN: Using default SA password, secret file not found at: $secretPath"
    }
}

if($sa_password -ne "_")
{
    Write-Verbose "Changing SA login credentials"
    $sqlcmd = "ALTER LOGIN sa with password=" +"'" + $sa_password + "'" + ";ALTER LOGIN sa ENABLE;"
    & sqlcmd -Q $sqlcmd
}

$attach_dbs_cleaned = $attach_dbs.TrimStart('\\').TrimEnd('\\')

$dbs = $attach_dbs_cleaned | ConvertFrom-Json

if ($null -ne $dbs -And $dbs.Length -gt 0)
{
    Write-Verbose "Attaching $($dbs.Length) database(s)"

    Foreach($db in $dbs) 
    {            
        $files = @();
        Foreach($file in $db.dbFiles)
        {
            $files += "(FILENAME = N'$($file)')";           
        }

        $files = $files -join ","
        $sqlcmd = "IF EXISTS (SELECT 1 FROM SYS.DATABASES WHERE NAME = '" + $($db.dbName) + "') BEGIN EXEC sp_detach_db [$($db.dbName)] END;CREATE DATABASE [$($db.dbName)] ON $($files) FOR ATTACH;"

        Write-Verbose "Invoke-Sqlcmd -Query $($sqlcmd)"
        & sqlcmd -Q $sqlcmd
    }
}

Write-Verbose "Started SQL Server."

Write-Verbose "Changing SQL Server server name to $($env:COMPUTERNAME)"
$sqlcmd = "EXEC sp_dropserver @@SERVERNAME;EXEC sp_addserver N'$env:COMPUTERNAME', 'local';"
& sqlcmd -Q $sqlcmd

Write-Verbose "Restarting SQL Server."
Stop-Service MSSQLSERVER
Start-Service MSSQLSERVER
Write-Verbose "Restarted SQL Server."

Write-Verbose "Tailing log..."
Get-Content -Path "C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Log\ERRORLOG" -Wait
  1. 將文件從 SQL 2019 安裝媒體複製到安裝子目錄(例如 C:\dockerfiles\setup)
  2. 在建構目錄(例如 C:\dockerfiles)的競賽中執行 docker build 來建構和標記自定義鏡像
docker build -t mssql-2019-windows-dev-rtm-example .
  1. 將圖像保存到 tar 文件
docker save --output "C:\temp\mssql-2019-windows-dev-rtm-example.tar" mssql-2019-windows-dev-rtm-example
  1. 將圖像複製到 Windows 伺服器
copy "C:\temp\mssql-2019-windows-dev-rtm-example.tar" "\\YourServer\c$\temp\mssql-2019-windows-dev-rtm-example.tar"
  1. 從 Windows 伺服器機器上的 tar 文件載入圖像:
docker load --input "C:\temp\mssql-2019-windows-dev-rtm-example.tar"
  1. 執行圖像的範例
docker run -d -p 14331:1433 -h sql2019 --name sql2019 -e "sa_password=y0ourS@pAssword" -e "ACCEPT_EULA=Y" -e attach_dbs="" --rm mssql-2019-windows-dev-rtm-example:latest

請注意,生產中尚不支持 Windows 容器,除非您加入 EA 預覽版,否則您目前只能使用 SQL 2019 映像。

引用自:https://dba.stackexchange.com/questions/276880