[Moby] Начальная инициализация wincon
This commit is contained in:
parent
69bfd9113c
commit
fa7b2748dc
72
README.md
72
README.md
@ -1,2 +1,70 @@
|
||||
# moby
|
||||
|
||||
# Эксперименты с Windows Containers
|
||||
|
||||
## Установка Docker (Moby)
|
||||
|
||||
Требования по ОС включают в себя Windows Server или Windows 10/11 Pro.
|
||||
|
||||
1. Конфигурируем выполнение сценариев ([PowerShell execution policies](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.5))
|
||||
```
|
||||
Get-ExecutionPolicy -List
|
||||
Get-ExecutionPolicy -Scope CurrentUser
|
||||
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||
```
|
||||
|
||||
2. Выполняем [установку](https://learn.microsoft.com/en-us/virtualization/windowscontainers/quick-start/set-up-environment?tabs=dockerce):
|
||||
```
|
||||
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/Windows-Containers/Main/helpful_tools/Install-DockerCE/install-docker-ce.ps1" -o install-docker-ce.ps1
|
||||
.\install-docker-ce.ps1
|
||||
```
|
||||
|
||||
3. Проверяем устнановку docker:
|
||||
```
|
||||
PS C:\WINDOWS\system32> docker info
|
||||
Client:
|
||||
Version: 28.2.2
|
||||
Context: default
|
||||
Debug Mode: false
|
||||
|
||||
Server:
|
||||
Containers: 0
|
||||
Running: 0
|
||||
Paused: 0
|
||||
Stopped: 0
|
||||
Images: 0
|
||||
Server Version: 28.2.2
|
||||
Storage Driver: windowsfilter
|
||||
Windows:
|
||||
Logging Driver: json-file
|
||||
Plugins:
|
||||
Volume: local
|
||||
Network: ics internal l2bridge l2tunnel nat null overlay private transparent
|
||||
Log: awslogs etwlogs fluentd gcplogs gelf json-file local splunk syslog
|
||||
CDI spec directories:
|
||||
/etc/cdi
|
||||
/var/run/cdi
|
||||
Swarm: inactive
|
||||
Default Isolation: hyperv
|
||||
Kernel Version: 10.0 26100 (26100.1.amd64fre.ge_release.240331-1435)
|
||||
Operating System: Microsoft Windows Version 24H2 (OS Build 26100.4351)
|
||||
OSType: windows
|
||||
Architecture: x86_64
|
||||
CPUs: 16
|
||||
Total Memory: 29.87GiB
|
||||
Name: Kubernetes
|
||||
ID: c5828016-f9e0-42ab-9b7c-a64742681a38
|
||||
Docker Root Dir: C:\ProgramData\docker
|
||||
Debug Mode: false
|
||||
Experimental: false
|
||||
Insecure Registries:
|
||||
::1/128
|
||||
127.0.0.0/8
|
||||
Live Restore Enabled: false
|
||||
Product License: Community Engine
|
||||
```
|
||||
|
||||
4. Пуллим [базовые](https://learn.microsoft.com/ru-ru/virtualization/windowscontainers/manage-containers/container-base-images) образы windows:
|
||||
```
|
||||
docker pull mcr.microsoft.com/windows/servercore:ltsc2025
|
||||
docker pull mcr.microsoft.com/windows/servercore:ltsc2022
|
||||
docker pull mcr.microsoft.com/windows/servercore:ltsc2019
|
||||
```
|
775
scripts/install-docker-ce.ps1
Normal file
775
scripts/install-docker-ce.ps1
Normal file
@ -0,0 +1,775 @@
|
||||
|
||||
############################################################
|
||||
# Script to install the community edition of docker on Windows
|
||||
############################################################
|
||||
|
||||
<#
|
||||
.NOTES
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Use of this sample source code is subject to the terms of the Microsoft
|
||||
license agreement under which you licensed this sample source code. If
|
||||
you did not accept the terms of the license agreement, you are not
|
||||
authorized to use this sample source code. For the terms of the license,
|
||||
please see the license agreement between you and Microsoft or, if applicable,
|
||||
see the LICENSE.RTF on your install media or the root of your tools installation.
|
||||
THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
|
||||
|
||||
.SYNOPSIS
|
||||
Installs the prerequisites for creating Windows containers
|
||||
|
||||
.DESCRIPTION
|
||||
Installs the prerequisites for creating Windows containers
|
||||
|
||||
.PARAMETER DockerPath
|
||||
Path to Docker.exe, can be local or URI
|
||||
|
||||
.PARAMETER DockerDPath
|
||||
Path to DockerD.exe, can be local or URI
|
||||
|
||||
.PARAMETER DockerVersion
|
||||
Version of docker to pull from download.docker.com - ! OVERRIDDEN BY DockerPath & DockerDPath
|
||||
|
||||
.PARAMETER ExternalNetAdapter
|
||||
Specify a specific network adapter to bind to a DHCP network
|
||||
|
||||
.PARAMETER SkipDefaultHost
|
||||
Prevents setting localhost as the default network configuration
|
||||
|
||||
.PARAMETER Force
|
||||
If a restart is required, forces an immediate restart.
|
||||
|
||||
.PARAMETER HyperV
|
||||
If passed, prepare the machine for Hyper-V containers
|
||||
|
||||
.PARAMETER NATSubnet
|
||||
Use to override the default Docker NAT Subnet when in NAT mode.
|
||||
|
||||
.PARAMETER NoRestart
|
||||
If a restart is required the script will terminate and will not reboot the machine
|
||||
|
||||
.PARAMETER ContainerBaseImage
|
||||
Use this to specify the URI of the container base image you wish to pre-pull
|
||||
|
||||
.PARAMETER Staging
|
||||
|
||||
.PARAMETER TransparentNetwork
|
||||
If passed, use DHCP configuration. Otherwise, will use default docker network (NAT). (alias -UseDHCP)
|
||||
|
||||
.PARAMETER TarPath
|
||||
Path to the .tar that is the base image to load into Docker.
|
||||
|
||||
.EXAMPLE
|
||||
.\install-docker-ce.ps1
|
||||
|
||||
#>
|
||||
#Requires -Version 5.0
|
||||
|
||||
[CmdletBinding(DefaultParameterSetName="Standard")]
|
||||
param(
|
||||
[string]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
$DockerPath = "default",
|
||||
|
||||
[string]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
$DockerDPath = "default",
|
||||
|
||||
[string]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
$DockerVersion = "latest",
|
||||
|
||||
[string]
|
||||
$ExternalNetAdapter,
|
||||
|
||||
[switch]
|
||||
$Force,
|
||||
|
||||
[switch]
|
||||
$HyperV,
|
||||
|
||||
[switch]
|
||||
$SkipDefaultHost,
|
||||
|
||||
[string]
|
||||
$NATSubnet,
|
||||
|
||||
[switch]
|
||||
$NoRestart,
|
||||
|
||||
[string]
|
||||
$ContainerBaseImage,
|
||||
|
||||
[Parameter(ParameterSetName="Staging", Mandatory)]
|
||||
[switch]
|
||||
$Staging,
|
||||
|
||||
[switch]
|
||||
[alias("UseDHCP")]
|
||||
$TransparentNetwork,
|
||||
|
||||
[string]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
$TarPath
|
||||
)
|
||||
|
||||
$global:RebootRequired = $false
|
||||
$global:ErrorFile = "$pwd\Install-ContainerHost.err"
|
||||
$global:BootstrapTask = "ContainerBootstrap"
|
||||
$global:HyperVImage = "NanoServer"
|
||||
$global:AdminPriviledges = $false
|
||||
|
||||
$global:DefaultDockerLocation = "https://download.docker.com/win/static/stable/x86_64/"
|
||||
$global:DockerDataPath = "$($env:ProgramData)\docker"
|
||||
$global:DockerServiceName = "docker"
|
||||
|
||||
function
|
||||
Restart-And-Run()
|
||||
{
|
||||
Test-Admin
|
||||
|
||||
Write-Output "Restart is required; restarting now..."
|
||||
|
||||
$argList = $script:MyInvocation.Line.replace($script:MyInvocation.InvocationName, "")
|
||||
|
||||
#
|
||||
# Update .\ to the invocation directory for the bootstrap
|
||||
#
|
||||
$scriptPath = $script:MyInvocation.MyCommand.Path
|
||||
|
||||
$argList = $argList -replace "\.\\", "$pwd\"
|
||||
|
||||
if ((Split-Path -Parent -Path $scriptPath) -ne $pwd)
|
||||
{
|
||||
$sourceScriptPath = $scriptPath
|
||||
$scriptPath = "$pwd\$($script:MyInvocation.MyCommand.Name)"
|
||||
|
||||
Copy-Item $sourceScriptPath $scriptPath
|
||||
}
|
||||
|
||||
Write-Output "Creating scheduled task action ($scriptPath $argList)..."
|
||||
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoExit $scriptPath $argList"
|
||||
|
||||
Write-Output "Creating scheduled task trigger..."
|
||||
$trigger = New-ScheduledTaskTrigger -AtLogOn
|
||||
|
||||
Write-Output "Registering script to re-run at next user logon..."
|
||||
Register-ScheduledTask -TaskName $global:BootstrapTask -Action $action -Trigger $trigger -RunLevel Highest | Out-Null
|
||||
|
||||
try
|
||||
{
|
||||
if ($Force)
|
||||
{
|
||||
Restart-Computer -Force
|
||||
}
|
||||
else
|
||||
{
|
||||
Restart-Computer
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error $_
|
||||
|
||||
Write-Output "Please restart your computer manually to continue script execution."
|
||||
}
|
||||
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
Install-Feature
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]
|
||||
$FeatureName
|
||||
)
|
||||
|
||||
Write-Output "Querying status of Windows feature: $FeatureName..."
|
||||
if (Get-Command Get-WindowsFeature -ErrorAction SilentlyContinue)
|
||||
{
|
||||
if ((Get-WindowsFeature $FeatureName).Installed)
|
||||
{
|
||||
Write-Output "Feature $FeatureName is already enabled."
|
||||
}
|
||||
else
|
||||
{
|
||||
Test-Admin
|
||||
|
||||
Write-Output "Enabling feature $FeatureName..."
|
||||
}
|
||||
|
||||
$featureInstall = Add-WindowsFeature $FeatureName
|
||||
|
||||
if ($featureInstall.RestartNeeded -eq "Yes")
|
||||
{
|
||||
$global:RebootRequired = $true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((Get-WindowsOptionalFeature -Online -FeatureName $FeatureName).State -eq "Disabled")
|
||||
{
|
||||
if (Test-Nano)
|
||||
{
|
||||
throw "This NanoServer deployment does not include $FeatureName. Please add the appropriate package"
|
||||
}
|
||||
|
||||
Test-Admin
|
||||
|
||||
Write-Output "Enabling feature $FeatureName..."
|
||||
$feature = Enable-WindowsOptionalFeature -Online -FeatureName $FeatureName -All -NoRestart
|
||||
|
||||
if ($feature.RestartNeeded -eq "True")
|
||||
{
|
||||
$global:RebootRequired = $true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Output "Feature $FeatureName is already enabled."
|
||||
|
||||
if (Test-Nano)
|
||||
{
|
||||
#
|
||||
# Get-WindowsEdition is not present on Nano. On Nano, we assume reboot is not needed
|
||||
#
|
||||
}
|
||||
elseif ((Get-WindowsEdition -Online).RestartNeeded)
|
||||
{
|
||||
$global:RebootRequired = $true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
New-ContainerTransparentNetwork
|
||||
{
|
||||
# Check if transparent network already created
|
||||
$networkList = docker network ls
|
||||
if ($networkList -match '\bTransparent\b')
|
||||
{
|
||||
Write-Output "Network with the name Transparent exists."
|
||||
return
|
||||
}
|
||||
|
||||
# Continue with network creation
|
||||
if ($ExternalNetAdapter)
|
||||
{
|
||||
$netAdapter = (Get-NetAdapter |? {$_.Name -eq "$ExternalNetAdapter"})[0]
|
||||
}
|
||||
else
|
||||
{
|
||||
$netAdapter = (Get-NetAdapter |? {($_.Status -eq 'Up') -and ($_.ConnectorPresent)})[0]
|
||||
}
|
||||
|
||||
Write-Output "Creating container network (Transparent)..."
|
||||
docker network create -d transparent -o com.docker.network.windowsshim.interface="$($netAdapter.Name)" "Transparent"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to create transparent network."
|
||||
}
|
||||
|
||||
# Transparent networks are not picked up by docker until after a service restart.
|
||||
if (Test-Docker)
|
||||
{
|
||||
Restart-Service -Name $global:DockerServiceName
|
||||
Wait-Docker
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
Install-ContainerHost
|
||||
{
|
||||
"If this file exists when Install-ContainerHost.ps1 exits, the script failed!" | Out-File -FilePath $global:ErrorFile
|
||||
|
||||
if (Test-Client)
|
||||
{
|
||||
if (-not $HyperV)
|
||||
{
|
||||
Write-Output "Enabling Hyper-V containers by default for Client SKU"
|
||||
$HyperV = $true
|
||||
}
|
||||
}
|
||||
#
|
||||
# Validate required Windows features
|
||||
#
|
||||
Install-Feature -FeatureName Containers
|
||||
|
||||
if ($HyperV)
|
||||
{
|
||||
Install-Feature -FeatureName Hyper-V
|
||||
}
|
||||
|
||||
if ($global:RebootRequired)
|
||||
{
|
||||
if ($NoRestart)
|
||||
{
|
||||
Write-Warning "A reboot is required; stopping script execution"
|
||||
exit
|
||||
}
|
||||
|
||||
Restart-And-Run
|
||||
}
|
||||
|
||||
#
|
||||
# Unregister the bootstrap task, if it was previously created
|
||||
#
|
||||
if ((Get-ScheduledTask -TaskName $global:BootstrapTask -ErrorAction SilentlyContinue) -ne $null)
|
||||
{
|
||||
Unregister-ScheduledTask -TaskName $global:BootstrapTask -Confirm:$false
|
||||
}
|
||||
|
||||
#
|
||||
# Install, register, and start Docker
|
||||
#
|
||||
if (Test-Docker)
|
||||
{
|
||||
Write-Output "Docker is already installed."
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($NATSubnet)
|
||||
{
|
||||
Install-Docker -DockerPath $DockerPath -DockerDPath $DockerDPath -NATSubnet $NATSubnet -ContainerBaseImage $ContainerBaseImage
|
||||
}
|
||||
else
|
||||
{
|
||||
Install-Docker -DockerPath $DockerPath -DockerDPath $DockerDPath -ContainerBaseImage $ContainerBaseImage
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Configure networking
|
||||
#
|
||||
if ($($PSCmdlet.ParameterSetName) -ne "Staging")
|
||||
{
|
||||
if ($TransparentNetwork)
|
||||
{
|
||||
Write-Output "Waiting for Hyper-V Management..."
|
||||
$networks = $null
|
||||
|
||||
try
|
||||
{
|
||||
$networks = Get-ContainerNetwork -ErrorAction SilentlyContinue
|
||||
}
|
||||
catch
|
||||
{
|
||||
#
|
||||
# If we can't query network, we are in bootstrap mode. Assume no networks
|
||||
#
|
||||
}
|
||||
|
||||
if ($networks.Count -eq 0)
|
||||
{
|
||||
Write-Output "Enabling container networking..."
|
||||
New-ContainerTransparentNetwork
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Output "Networking is already configured. Confirming configuration..."
|
||||
|
||||
$transparentNetwork = $networks |? { $_.Mode -eq "Transparent" }
|
||||
|
||||
if ($transparentNetwork -eq $null)
|
||||
{
|
||||
Write-Output "We didn't find a configured external network; configuring now..."
|
||||
New-ContainerTransparentNetwork
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($ExternalNetAdapter)
|
||||
{
|
||||
$netAdapters = (Get-NetAdapter |? {$_.Name -eq "$ExternalNetAdapter"})
|
||||
|
||||
if ($netAdapters.Count -eq 0)
|
||||
{
|
||||
throw "No adapters found that match the name $ExternalNetAdapter"
|
||||
}
|
||||
|
||||
$netAdapter = $netAdapters[0]
|
||||
$transparentNetwork = $networks |? { $_.NetworkAdapterName -eq $netAdapter.InterfaceDescription }
|
||||
|
||||
if ($transparentNetwork -eq $null)
|
||||
{
|
||||
throw "One or more external networks are configured, but not on the requested adapter ($ExternalNetAdapter)"
|
||||
}
|
||||
|
||||
Write-Output "Configured transparent network found: $($transparentNetwork.Name)"
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Output "Configured transparent network found: $($transparentNetwork.Name)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($TarPath)
|
||||
{
|
||||
cmd /c "docker load -i `"$TarPath`""
|
||||
}
|
||||
|
||||
Remove-Item $global:ErrorFile
|
||||
|
||||
Write-Output "Script complete!"
|
||||
}
|
||||
|
||||
function
|
||||
Copy-File
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]
|
||||
$SourcePath,
|
||||
|
||||
[string]
|
||||
$DestinationPath
|
||||
)
|
||||
|
||||
if ($SourcePath -eq $DestinationPath)
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
if (Test-Path $SourcePath)
|
||||
{
|
||||
Copy-Item -Path $SourcePath -Destination $DestinationPath
|
||||
}
|
||||
elseif (($SourcePath -as [System.URI]).AbsoluteURI -ne $null)
|
||||
{
|
||||
if (Test-Nano)
|
||||
{
|
||||
$handler = New-Object System.Net.Http.HttpClientHandler
|
||||
$client = New-Object System.Net.Http.HttpClient($handler)
|
||||
$client.Timeout = New-Object System.TimeSpan(0, 30, 0)
|
||||
$cancelTokenSource = [System.Threading.CancellationTokenSource]::new()
|
||||
$responseMsg = $client.GetAsync([System.Uri]::new($SourcePath), $cancelTokenSource.Token)
|
||||
$responseMsg.Wait()
|
||||
|
||||
if (!$responseMsg.IsCanceled)
|
||||
{
|
||||
$response = $responseMsg.Result
|
||||
if ($response.IsSuccessStatusCode)
|
||||
{
|
||||
$downloadedFileStream = [System.IO.FileStream]::new($DestinationPath, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
|
||||
$copyStreamOp = $response.Content.CopyToAsync($downloadedFileStream)
|
||||
$copyStreamOp.Wait()
|
||||
$downloadedFileStream.Close()
|
||||
if ($copyStreamOp.Exception -ne $null)
|
||||
{
|
||||
throw $copyStreamOp.Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($PSVersionTable.PSVersion.Major -ge 5)
|
||||
{
|
||||
#
|
||||
# We disable progress display because it kills performance for large downloads (at least on 64-bit PowerShell)
|
||||
#
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
Invoke-WebRequest -Uri $SourcePath -OutFile $DestinationPath -UseBasicParsing
|
||||
$ProgressPreference = 'Continue'
|
||||
}
|
||||
else
|
||||
{
|
||||
$webClient = New-Object System.Net.WebClient
|
||||
$webClient.DownloadFile($SourcePath, $DestinationPath)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Cannot copy from $SourcePath"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
Test-Admin()
|
||||
{
|
||||
# Get the ID and security principal of the current user account
|
||||
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
|
||||
|
||||
# Get the security principal for the Administrator role
|
||||
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
|
||||
|
||||
# Check to see if we are currently running "as Administrator"
|
||||
if ($myWindowsPrincipal.IsInRole($adminRole))
|
||||
{
|
||||
$global:AdminPriviledges = $true
|
||||
return
|
||||
}
|
||||
else
|
||||
{
|
||||
#
|
||||
# We are not running "as Administrator"
|
||||
# Exit from the current, unelevated, process
|
||||
#
|
||||
throw "You must run this script as administrator"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
Test-Client()
|
||||
{
|
||||
return (-not ((Get-Command Get-WindowsFeature -ErrorAction SilentlyContinue) -or (Test-Nano)))
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
Test-Nano()
|
||||
{
|
||||
$EditionId = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name 'EditionID').EditionId
|
||||
|
||||
return (($EditionId -eq "ServerStandardNano") -or
|
||||
($EditionId -eq "ServerDataCenterNano") -or
|
||||
($EditionId -eq "NanoServer") -or
|
||||
($EditionId -eq "ServerTuva"))
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
Wait-Network()
|
||||
{
|
||||
$connectedAdapter = Get-NetAdapter |? ConnectorPresent
|
||||
|
||||
if ($connectedAdapter -eq $null)
|
||||
{
|
||||
throw "No connected network"
|
||||
}
|
||||
|
||||
$startTime = Get-Date
|
||||
$timeElapsed = $(Get-Date) - $startTime
|
||||
|
||||
while ($($timeElapsed).TotalMinutes -lt 5)
|
||||
{
|
||||
$readyNetAdapter = $connectedAdapter |? Status -eq 'Up'
|
||||
|
||||
if ($readyNetAdapter -ne $null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Write-Output "Waiting for network connectivity..."
|
||||
Start-Sleep -sec 5
|
||||
|
||||
$timeElapsed = $(Get-Date) - $startTime
|
||||
}
|
||||
|
||||
throw "Network not connected after 5 minutes"
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
Install-Docker()
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
$DockerPath = "default",
|
||||
|
||||
[string]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
$DockerDPath = "default",
|
||||
|
||||
[string]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
$NATSubnet,
|
||||
|
||||
[switch]
|
||||
$SkipDefaultHost,
|
||||
|
||||
[string]
|
||||
$ContainerBaseImage
|
||||
)
|
||||
|
||||
Test-Admin
|
||||
|
||||
#If one of these are set to default then the whole .zip needs to be downloaded anyways.
|
||||
Write-Output "DOCKER $DockerPath"
|
||||
if ($DockerPath -eq "default" -or $DockerDPath -eq "default") {
|
||||
Write-Output "Checking Docker versions"
|
||||
#Get the list of .zip packages available from docker.
|
||||
$availableVersions = ((Invoke-WebRequest -Uri $DefaultDockerLocation -UseBasicParsing).Links | Where-Object {$_.href -like "docker*"}).href | Sort-Object -Descending
|
||||
|
||||
#Parse the versions from the file names
|
||||
$availableVersions = ($availableVersions | Select-String -Pattern "docker-(\d+\.\d+\.\d+).+" -AllMatches | Select-Object -Expand Matches | %{ $_.Groups[1].Value })
|
||||
$version = $availableVersions[0]
|
||||
|
||||
if($DockerVersion -ne "latest") {
|
||||
$version = $DockerVersion
|
||||
if(!($availableVersions | Select-String $DockerVersion)) {
|
||||
Write-Error "Docker version supplied $DockerVersion was invalid, please choose from the list of available versions: $availableVersions"
|
||||
throw "Invalid docker version supplied."
|
||||
}
|
||||
}
|
||||
|
||||
$zipUrl = $global:DefaultDockerLocation + "docker-$version.zip"
|
||||
$destinationFolder = "$env:UserProfile\DockerDownloads"
|
||||
|
||||
if(!(Test-Path "$destinationFolder")) {
|
||||
md -Path $destinationFolder | Out-Null
|
||||
} elseif(Test-Path "$destinationFolder\docker-$version") {
|
||||
Remove-Item -Recurse -Force "$destinationFolder\docker-$version"
|
||||
}
|
||||
|
||||
Write-Output "Downloading $zipUrl to $destinationFolder\docker-$version.zip"
|
||||
Copy-File -SourcePath $zipUrl -DestinationPath "$destinationFolder\docker-$version.zip"
|
||||
|
||||
#Prevent issues with CLI non-interactive execution on Window Server 2019
|
||||
$global:ProgressPreference = "SilentlyContinue"
|
||||
Expand-Archive -Path "$destinationFolder\docker-$version.zip" -DestinationPath "$destinationFolder\docker-$version"
|
||||
$global:ProgressPreference = "Continue"
|
||||
|
||||
if($DockerPath -eq "default") {
|
||||
$DockerPath = "$destinationFolder\docker-$version\docker\docker.exe"
|
||||
}
|
||||
if($DockerDPath -eq "default") {
|
||||
$DockerDPath = "$destinationFolder\docker-$version\docker\dockerd.exe"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output "Installing Docker... $DockerPath"
|
||||
Copy-File -SourcePath $DockerPath -DestinationPath $env:windir\System32\docker.exe
|
||||
|
||||
Write-Output "Installing Docker daemon... $DockerDPath"
|
||||
Copy-File -SourcePath $DockerDPath -DestinationPath $env:windir\System32\dockerd.exe
|
||||
|
||||
$dockerConfigPath = Join-Path $global:DockerDataPath "config"
|
||||
|
||||
if (!(Test-Path $dockerConfigPath))
|
||||
{
|
||||
md -Path $dockerConfigPath | Out-Null
|
||||
}
|
||||
|
||||
#
|
||||
# Register the docker service.
|
||||
# Configuration options should be placed at %programdata%\docker\config\daemon.json
|
||||
#
|
||||
Write-Output "Configuring the docker service..."
|
||||
|
||||
$daemonSettings = New-Object PSObject
|
||||
|
||||
$certsPath = Join-Path $global:DockerDataPath "certs.d"
|
||||
|
||||
if (Test-Path $certsPath)
|
||||
{
|
||||
$daemonSettings | Add-Member NoteProperty hosts @("npipe://", "0.0.0.0:2376")
|
||||
$daemonSettings | Add-Member NoteProperty tlsverify true
|
||||
$daemonSettings | Add-Member NoteProperty tlscacert (Join-Path $certsPath "ca.pem")
|
||||
$daemonSettings | Add-Member NoteProperty tlscert (Join-Path $certsPath "server-cert.pem")
|
||||
$daemonSettings | Add-Member NoteProperty tlskey (Join-Path $certsPath "server-key.pem")
|
||||
}
|
||||
elseif (!$SkipDefaultHost.IsPresent)
|
||||
{
|
||||
# Default local host
|
||||
$daemonSettings | Add-Member NoteProperty hosts @("npipe://")
|
||||
}
|
||||
|
||||
if ($NATSubnet -ne "")
|
||||
{
|
||||
$daemonSettings | Add-Member NoteProperty fixed-cidr $NATSubnet
|
||||
}
|
||||
|
||||
$daemonSettingsFile = Join-Path $dockerConfigPath "daemon.json"
|
||||
|
||||
$daemonSettings | ConvertTo-Json | Out-File -FilePath $daemonSettingsFile -Encoding ASCII
|
||||
|
||||
& dockerd --register-service --service-name $global:DockerServiceName
|
||||
|
||||
Start-Docker
|
||||
|
||||
#
|
||||
# Waiting for docker to come to steady state
|
||||
#
|
||||
Wait-Docker
|
||||
|
||||
if(-not [string]::IsNullOrEmpty($ContainerBaseImage)) {
|
||||
Write-Output "Attempting to pull specified base image: $ContainerBaseImage"
|
||||
docker pull $ContainerBaseImage
|
||||
}
|
||||
|
||||
Write-Output "The following images are present on this machine:"
|
||||
|
||||
docker images -a | Write-Output
|
||||
|
||||
Write-Output ""
|
||||
}
|
||||
|
||||
function
|
||||
Start-Docker()
|
||||
{
|
||||
Start-Service -Name $global:DockerServiceName
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
Stop-Docker()
|
||||
{
|
||||
Stop-Service -Name $global:DockerServiceName
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
Test-Docker()
|
||||
{
|
||||
$service = Get-Service -Name $global:DockerServiceName -ErrorAction SilentlyContinue
|
||||
|
||||
return ($service -ne $null)
|
||||
}
|
||||
|
||||
|
||||
function
|
||||
Wait-Docker()
|
||||
{
|
||||
Write-Output "Waiting for Docker daemon..."
|
||||
$dockerReady = $false
|
||||
$startTime = Get-Date
|
||||
|
||||
while (-not $dockerReady)
|
||||
{
|
||||
try
|
||||
{
|
||||
docker version | Out-Null
|
||||
|
||||
if (-not $?)
|
||||
{
|
||||
throw "Docker daemon is not running yet"
|
||||
}
|
||||
|
||||
$dockerReady = $true
|
||||
}
|
||||
catch
|
||||
{
|
||||
$timeElapsed = $(Get-Date) - $startTime
|
||||
|
||||
if ($($timeElapsed).TotalMinutes -ge 1)
|
||||
{
|
||||
throw "Docker Daemon did not start successfully within 1 minute."
|
||||
}
|
||||
|
||||
# Swallow error and try again
|
||||
Start-Sleep -sec 1
|
||||
}
|
||||
}
|
||||
Write-Output "Successfully connected to Docker Daemon."
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Install-ContainerHost
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error $_
|
||||
}
|
Loading…
Reference in New Issue
Block a user