diff --git a/.github/workflows/flannel.yml b/.github/workflows/flannel.yml new file mode 100644 index 00000000..901e22b8 --- /dev/null +++ b/.github/workflows/flannel.yml @@ -0,0 +1,33 @@ +name: flannel-images + +on: + push: + tags: + - v* + pull_request: + paths: + - "kubeadm/flannel/**" + - "kubeadm/buildx.psm1" + - ".github/workflows/flannel.yml" + branches: + - master + +jobs: + build: + runs-on: ubuntu-20.04 + defaults: + run: + shell: pwsh + working-directory: ./kubeadm/flannel + steps: + - uses: actions/checkout@v2 + - name: Build and push images + if: ${{ github.event_name == 'push' }} + run: | + echo ${{ secrets.DOCKER_SECRET }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin + $gittag = '-'+(($env:GITHUB_REF -split '/' | select-object -skip 2) -join '-') + ./build.ps1 -push -tagSuffix $gittag + - name: Build images (without push) + if: ${{ github.event_name == 'pull_request' }} + run: | + ./build.ps1 diff --git a/.github/workflows/kube-proxy.yml b/.github/workflows/kube-proxy.yml index dde882ca..af8bafa3 100644 --- a/.github/workflows/kube-proxy.yml +++ b/.github/workflows/kube-proxy.yml @@ -3,15 +3,29 @@ name: kube-proxy-images on: schedule: - cron: "0 0 * * *" + pull_request: + paths: + - "kubeadm/kube-proxy/**" + - "kubeadm/buildx.psm1" + - ".github/workflows/kube-proxy.yml" + branches: + - master jobs: build: - runs-on: windows-2019 + runs-on: ubuntu-20.04 + defaults: + run: + shell: pwsh + working-directory: ./kubeadm/kube-proxy steps: - uses: actions/checkout@v2 - - uses: azure/docker-login@v1 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_SECRET }} - - name: Build - run: go run kubeadm/hack/publish-kubeproxy.go kubeadm/kube-proxy + - name: Build and push images + if: ${{ github.event_name == 'schedule' }} + run: | + echo ${{ secrets.DOCKER_SECRET }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin + ./build.ps1 -push + - name: Build images (without push) + if: ${{ github.event_name == 'pull_request' }} + run: | + ./build.ps1 diff --git a/kubeadm/buildx.psm1 b/kubeadm/buildx.psm1 new file mode 100644 index 00000000..7c0f45f7 --- /dev/null +++ b/kubeadm/buildx.psm1 @@ -0,0 +1,79 @@ +function Set-Builder() +{ + $env:DOCKER_CLI_EXPERIMENTAL = "enabled" + & docker buildx create --name img-builder --use --driver docker-container --driver-opt image=moby/buildkit:v0.7.2 +} + +function New-Build() +{ + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [string]$name, + [Parameter(Mandatory = $true)] + [ValidateSet("docker", "registry")] + [string]$output, + [Parameter(Mandatory = $true)] + [string[]]$args + ) + + $command = "docker buildx build --platform windows/amd64 --output=type=$output -f Dockerfile -t $name" + foreach($arg in $args) + { + $command = "$command --build-arg=$arg" + } + $command = "$command ." + Write-Host $command + Invoke-Expression $command +} + +function Get-ManifestName([string]$name) +{ + if (($name -split "/").Length -eq 1) { + $name = "library/$name" + } + if (($name -split "/").Length -eq 2) { + $name = "docker.io/$name" + } + return ($name -replace "/", "_") -replace ":", "-" +} + +function Push-Manifest([string]$name, [string[]]$items, [string[]]$bases) +{ + $folder = Get-ManifestName -name $name + if (Test-Path "~/.docker/manifests/$folder") + { + Write-Warning "Manifest $name already exists and will be overridden." + & docker manifest rm $name | out-null + } + + $command = "docker manifest create $name"; + foreach($item in $items) + { + $command = "$command --amend $item" + } + Write-Host $command + Invoke-Expression $command + + # Use `docker manifest annotate` instead of this when docker cli 20.* is ready. + # See details: https://github.com/docker/cli/pull/2578 + for ($i = 0; $i -lt $items.Length; $i++) { + $base = $bases[$i] + $item = $items[$i] + + $manifest = $(docker manifest inspect $base -v) | ConvertFrom-Json + $platform = $manifest.Descriptor.platform + + $img = Get-ManifestName -name $item + + $manifest = Get-Content "~/.docker/manifests/$folder/$img" | ConvertFrom-Json + $manifest.Descriptor.platform = $platform + $manifest | ConvertTo-Json -Depth 10 -Compress | Set-Content "~/.docker/manifests/$folder/$img" + } + + & docker manifest push $name +} + +Export-ModuleMember Set-Builder +Export-ModuleMember New-Build +Export-ModuleMember Push-Manifest diff --git a/kubeadm/flannel/Dockerfile b/kubeadm/flannel/Dockerfile index 09690ff8..dddf3022 100644 --- a/kubeadm/flannel/Dockerfile +++ b/kubeadm/flannel/Dockerfile @@ -1,30 +1,39 @@ -ARG servercoreTag="ltsc2019" -ARG cniVersion="0.8.5" -ARG golangTag=windowsservercore-1809 +ARG BASE="mcr.microsoft.com/powershell:nanoserver-1809" +ARG cniVersion="0.8.7" +ARG flannelVersion="0.13.0" -FROM golang:${golangTag} as builder -ADD setup.go build/ -RUN go build -o build/setup.exe build/setup.go - -FROM mcr.microsoft.com/windows/servercore:${servercoreTag} -SHELL ["powershell", "-NoLogo", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] +FROM --platform=linux/amd64 golang as setup +ENV GOOS=windows +ENV GOARCH=amd64 +WORKDIR /build +ADD setup.go . +RUN go build -o setup.exe setup.go +FROM --platform=linux/amd64 curlimages/curl as bins ARG cniVersion +ARG flannelVersion + +WORKDIR /utils +RUN curl -Lo wins.exe https://github.com/rancher/wins/releases/download/v0.0.4/wins.exe +RUN curl -Lo yq.exe https://github.com/mikefarah/yq/releases/download/2.4.1/yq_windows_amd64.exe + +WORKDIR /cni +RUN curl -Lo cni.tgz https://github.com/containernetworking/plugins/releases/download/v${cniVersion}/cni-plugins-windows-amd64-v${cniVersion}.tgz +RUN tar -xf cni.tgz +RUN rm cni.tgz + +WORKDIR /flannel +RUN curl -Lo flanneld.exe https://github.com/coreos/flannel/releases/download/v${flannelVersion}/flanneld.exe -RUN mkdir -force C:\k\flannel; \ - pushd C:\k\flannel; \ - curl.exe -LO https://github.com/coreos/flannel/releases/download/v0.12.0/flanneld.exe +FROM $BASE -ADD hns.psm1 /k/flannel -COPY --from=builder /gopath/build/setup.exe /k/flannel/setup.exe +ENV PATH="C:\Program Files\PowerShell;C:\utils;C:\Windows\system32;C:\Windows;" -RUN mkdir C:\cni; \ - pushd C:\cni; \ - curl.exe -Lo cni.tgz https://github.com/containernetworking/plugins/releases/download/v${env:cniVersion}/cni-plugins-windows-amd64-v${env:cniVersion}.tgz; \ - tar -xf cni.tgz; \ - rm cni.tgz +# wins.exe doesn't work in nanoserver with default ContainerUser. +USER ContainerAdministrator -RUN mkdir C:\utils; \ - curl.exe -Lo C:\utils\wins.exe https://github.com/rancher/wins/releases/download/v0.0.4/wins.exe; \ - curl.exe -Lo C:\utils\yq.exe https://github.com/mikefarah/yq/releases/download/2.4.1/yq_windows_amd64.exe; \ - "[Environment]::SetEnvironmentVariable('PATH', $env:PATH + ';C:\utils', [EnvironmentVariableTarget]::Machine)" +COPY --from=bins /utils /utils +COPY --from=bins /cni /cni +ADD https://raw.githubusercontent.com/microsoft/SDN/master/Kubernetes/windows/hns.psm1 /k/flannel/hns.psm1 +COPY --from=setup /build/setup.exe /k/flannel/setup.exe +COPY --from=bins /flannel/flanneld.exe /k/flannel/flanneld.exe diff --git a/kubeadm/flannel/build.ps1 b/kubeadm/flannel/build.ps1 new file mode 100644 index 00000000..da1908dd --- /dev/null +++ b/kubeadm/flannel/build.ps1 @@ -0,0 +1,35 @@ +param( + [switch] $push, + [string] $image = "sigwindowstools/flannel", + [string] $tagSuffix = "" +) + +$output="docker" +if ($push.IsPresent) { + $output="registry" +} + +Import-Module "../buildx.psm1" +Set-Builder + +$config = Get-Content .\buildconfig.json | ConvertFrom-Json +foreach ($flannel in $config.flannel) +{ + Write-Host "Build images for flannel version: $flannel" + + [string[]]$items = @() + [string[]]$bases = @() + foreach($tag in $config.tagsMap) + { + $base = "$($config.baseimage):$($tag.source)" + $current = "$($image):v$($flannel)-$($tag.target)$($tagSuffix)" + $bases += $base + $items += $current + New-Build -name $current -output $output -args @("BASE=$base", "flannelVersion=$flannel") + } + + if ($push.IsPresent) + { + Push-Manifest -name "$($image):v$flannel-nanoserver" -items $items -bases $bases + } +} diff --git a/kubeadm/flannel/buildconfig.json b/kubeadm/flannel/buildconfig.json new file mode 100644 index 00000000..b25cd06e --- /dev/null +++ b/kubeadm/flannel/buildconfig.json @@ -0,0 +1,13 @@ +{ + "flannel": [ + "0.12.0", + "0.13.0" + ], + "baseimage": "mcr.microsoft.com/powershell", + "tagsMap":[ + {"source":"nanoserver-2004","target":"2004"}, + {"source":"nanoserver-1909","target":"1909"}, + {"source":"nanoserver-1903","target":"1903"}, + {"source":"nanoserver-1809","target":"1809"} + ] +} \ No newline at end of file diff --git a/kubeadm/flannel/flannel-host-gw.yml b/kubeadm/flannel/flannel-host-gw.yml index afb21e89..9d89078b 100644 --- a/kubeadm/flannel/flannel-host-gw.yml +++ b/kubeadm/flannel/flannel-host-gw.yml @@ -179,9 +179,9 @@ spec: effect: NoSchedule containers: - name: kube-flannel - image: sigwindowstools/flannel:0.12.0 + image: sigwindowstools/flannel:v0.13.0-nanoserver command: - - powershell + - pwsh args: - -file - /etc/kube-flannel-windows/run.ps1 diff --git a/kubeadm/flannel/flannel-overlay.yml b/kubeadm/flannel/flannel-overlay.yml index 0c5eb3ab..775185cf 100644 --- a/kubeadm/flannel/flannel-overlay.yml +++ b/kubeadm/flannel/flannel-overlay.yml @@ -165,9 +165,9 @@ spec: effect: NoSchedule containers: - name: kube-flannel - image: sigwindowstools/flannel:0.12.0 + image: sigwindowstools/flannel:v0.13.0-nanoserver command: - - powershell + - pwsh args: - -file - /etc/kube-flannel-windows/run.ps1 diff --git a/kubeadm/flannel/hns.psm1 b/kubeadm/flannel/hns.psm1 deleted file mode 100644 index f94f1860..00000000 --- a/kubeadm/flannel/hns.psm1 +++ /dev/null @@ -1,502 +0,0 @@ -######################################################################### -# Global Initialize -function Get-VmComputeNativeMethods() -{ - $signature = @' - [DllImport("vmcompute.dll")] - public static extern void HNSCall([MarshalAs(UnmanagedType.LPWStr)] string method, [MarshalAs(UnmanagedType.LPWStr)] string path, [MarshalAs(UnmanagedType.LPWStr)] string request, [MarshalAs(UnmanagedType.LPWStr)] out string response); -'@ - - # Compile into runtime type - Add-Type -MemberDefinition $signature -Namespace VmCompute.PrivatePInvoke -Name NativeMethods -PassThru -} - -######################################################################### -# Configuration -######################################################################### -function Get-HnsSwitchExtensions -{ - param - ( - [parameter(Mandatory=$true)] [string] $NetworkId - ) - - return (Get-HNSNetwork $NetworkId).Extensions -} - -function Set-HnsSwitchExtension -{ - param - ( - [parameter(Mandatory=$true)] [string] $NetworkId, - [parameter(Mandatory=$true)] [string] $ExtensionId, - [parameter(Mandatory=$true)] [bool] $state - ) - - # { "Extensions": [ { "Id": "...", "IsEnabled": true|false } ] } - $req = @{ - "Extensions"=@(@{ - "Id"=$ExtensionId; - "IsEnabled"=$state; - };) - } - Invoke-HNSRequest -Method POST -Type networks -Id $NetworkId -Data (ConvertTo-Json $req) -} - -######################################################################### -# Activities -######################################################################### -function Get-HNSActivities -{ - [cmdletbinding()]Param() - return Invoke-HNSRequest -Type activities -Method GET -} - -######################################################################### -# PolicyLists -######################################################################### -function Get-HNSPolicyList { - [cmdletbinding()]Param() - return Invoke-HNSRequest -Type policylists -Method GET -} - -function Remove-HnsPolicyList -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [Object[]] $InputObjects - ) - begin {$Objects = @()} - process {$Objects += $InputObjects; } - end { - $Objects | foreach { Invoke-HNSRequest -Method DELETE -Type policylists -Id $_.Id } - } -} - -function New-HnsRoute { - param - ( - [parameter(Mandatory = $false)] [Guid[]] $Endpoints = $null, - [parameter(Mandatory = $true)] [string] $DestinationPrefix, - [parameter(Mandatory = $false)] [switch] $EncapEnabled - ) - - $policyLists = @{ - References = @( - get-endpointReferences $Endpoints; - ); - Policies = @( - @{ - Type = "ROUTE"; - DestinationPrefix = $DestinationPrefix; - NeedEncap = $EncapEnabled.IsPresent; - } - ); - } - - Invoke-HNSRequest -Method POST -Type policylists -Data (ConvertTo-Json $policyLists -Depth 10) -} - -function New-HnsLoadBalancer { - param - ( - [parameter(Mandatory = $false)] [Guid[]] $Endpoints = $null, - [parameter(Mandatory = $true)] [int] $InternalPort, - [parameter(Mandatory = $true)] [int] $ExternalPort, - [parameter(Mandatory = $false)] [string] $Vip - ) - - $policyLists = @{ - References = @( - get-endpointReferences $Endpoints; - ); - Policies = @( - @{ - Type = "ELB"; - InternalPort = $InternalPort; - ExternalPort = $ExternalPort; - VIPs = @($Vip); - } - ); - } - - Invoke-HNSRequest -Method POST -Type policylists -Data ( ConvertTo-Json $policyLists -Depth 10) -} - - -function get-endpointReferences { - param - ( - [parameter(Mandatory = $true)] [Guid[]] $Endpoints = $null - ) - if ($Endpoints ) { - $endpointReference = @() - foreach ($endpoint in $Endpoints) - { - $endpointReference += "/endpoints/$endpoint" - } - return $endpointReference - } - return @() -} - -######################################################################### -# Networks -######################################################################### -function New-HnsNetwork -{ - param - ( - [parameter(Mandatory=$false, Position=0)] - [string] $JsonString, - [ValidateSet('ICS', 'Internal', 'Transparent', 'NAT', 'Overlay', 'L2Bridge', 'L2Tunnel', 'Layered', 'Private')] - [parameter(Mandatory = $false, Position = 0)] - [string] $Type, - [parameter(Mandatory = $false)] [string] $Name, - [parameter(Mandatory = $false)] $AddressPrefix, - [parameter(Mandatory = $false)] $Gateway, - [HashTable[]][parameter(Mandatory=$false)] $SubnetPolicies, # @(@{VSID = 4096; }) - - [parameter(Mandatory = $false)] [switch] $IPv6, - [parameter(Mandatory = $false)] [string] $DNSServer, - [parameter(Mandatory = $false)] [string] $AdapterName, - [HashTable][parameter(Mandatory=$false)] $AdditionalParams, # @ {"ICSFlags" = 0; } - [HashTable][parameter(Mandatory=$false)] $NetworkSpecificParams # @ {"InterfaceConstraint" = ""; } - ) - - Begin { - if (!$JsonString) { - $netobj = @{ - Type = $Type; - }; - - if ($Name) { - $netobj += @{ - Name = $Name; - } - } - - # Coalesce prefix/gateway into subnet objects. - if ($AddressPrefix) { - $subnets += @() - $prefixes = @($AddressPrefix) - $gateways = @($Gateway) - - $len = $prefixes.length - for ($i = 0; $i -lt $len; $i++) { - $subnet = @{ AddressPrefix = $prefixes[$i]; } - if ($i -lt $gateways.length -and $gateways[$i]) { - $subnet += @{ GatewayAddress = $gateways[$i]; } - - if ($SubnetPolicies) { - $subnet.Policies += $SubnetPolicies - } - } - - $subnets += $subnet - } - - $netobj += @{ Subnets = $subnets } - } - - if ($IPv6.IsPresent) { - $netobj += @{ IPv6 = $true } - } - - if ($AdapterName) { - $netobj += @{ NetworkAdapterName = $AdapterName; } - } - - if ($AdditionalParams) { - $netobj += @{ - AdditionalParams = @{} - } - - foreach ($param in $AdditionalParams.Keys) { - $netobj.AdditionalParams += @{ - $param = $AdditionalParams[$param]; - } - } - } - - if ($NetworkSpecificParams) { - $netobj += $NetworkSpecificParams - } - - $JsonString = ConvertTo-Json $netobj -Depth 10 - } - - } - Process{ - return Invoke-HnsRequest -Method POST -Type networks -Data $JsonString - } -} - - -######################################################################### -# Endpoints -######################################################################### -function New-HnsEndpoint -{ - param - ( - [parameter(Mandatory=$false, Position = 0)] [string] $JsonString = $null, - [parameter(Mandatory = $false, Position = 0)] [Guid] $NetworkId, - [parameter(Mandatory = $false)] [string] $Name, - [parameter(Mandatory = $false)] [string] $IPAddress, - [parameter(Mandatory = $false)] [string] $Gateway, - [parameter(Mandatory = $false)] [string] $MacAddress, - [parameter(Mandatory = $false)] [switch] $EnableOutboundNat - ) - - begin - { - if ($JsonString) - { - $EndpointData = $JsonString | ConvertTo-Json | ConvertFrom-Json - } - else - { - $endpoint = @{ - VirtualNetwork = $NetworkId; - Policies = @(); - } - - if ($Name) { - $endpoint += @{ - Name = $Name; - } - } - - if ($MacAddress) { - $endpoint += @{ - MacAddress = $MacAddress; - } - } - - if ($IPAddress) { - $endpoint += @{ - IPAddress = $IPAddress; - } - } - - if ($Gateway) { - $endpoint += @{ - GatewayAddress = $Gateway; - } - } - - if ($EnableOutboundNat) { - $endpoint.Policies += @{ - Type = "OutBoundNAT"; - } - - } - # Try to Generate the data - $EndpointData = convertto-json $endpoint - } - } - - Process - { - return Invoke-HNSRequest -Method POST -Type endpoints -Data $EndpointData - } -} - - -function New-HnsRemoteEndpoint -{ - param - ( - [parameter(Mandatory = $true)] [Guid] $NetworkId, - [parameter(Mandatory = $false)] [string] $IPAddress, - [parameter(Mandatory = $false)] [string] $MacAddress - ) - - $remoteEndpoint = @{ - ID = [Guid]::NewGuid(); - VirtualNetwork = $NetworkId; - IPAddress = $IPAddress; - MacAddress = $MacAddress; - IsRemoteEndpoint = $true; - } - - return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $remoteEndpoint -Depth 10) - -} - - -function Attach-HnsHostEndpoint -{ - param - ( - [parameter(Mandatory=$true)] [Guid] $EndpointID, - [parameter(Mandatory=$true)] [int] $CompartmentID - ) - $request = @{ - SystemType = "Host"; - CompartmentId = $CompartmentID; - }; - - return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request) -Action "attach" -Id $EndpointID -} - -function Attach-HNSVMEndpoint -{ - param - ( - [parameter(Mandatory=$true)] [Guid] $EndpointID, - [parameter(Mandatory=$true)] [string] $VMNetworkAdapterName - ) - - $request = @{ - VirtualNicName = $VMNetworkAdapterName; - SystemType = "VirtualMachine"; - }; - return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "attach" -Id $EndpointID - -} - -function Attach-HNSEndpoint -{ - param - ( - [parameter(Mandatory=$true)] [Guid] $EndpointID, - [parameter(Mandatory=$true)] [int] $CompartmentID, - [parameter(Mandatory=$true)] [string] $ContainerID - ) - $request = @{ - ContainerId = $ContainerID; - SystemType="Container"; - CompartmentId = $CompartmentID; - }; - - return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request) -Action "attach" -Id $EndpointID -} - -function Detach-HNSVMEndpoint -{ - param - ( - [parameter(Mandatory=$true)] [Guid] $EndpointID - ) - $request = @{ - SystemType = "VirtualMachine"; - }; - - return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "detach" -Id $EndpointID -} - -function Detach-HNSHostEndpoint -{ - param - ( - [parameter(Mandatory=$true)] [Guid] $EndpointID - ) - $request = @{ - SystemType = "Host"; - }; - - return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "detach" -Id $EndpointID -} - -function Detach-HNSEndpoint -{ - param - ( - [parameter(Mandatory=$true)] [Guid] $EndpointID, - [parameter(Mandatory=$true)] [string] $ContainerID - ) - - $request = @{ - ContainerId = $ContainerID; - SystemType="Container"; - }; - - return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "detach" -Id $EndpointID -} -######################################################################### - -function Invoke-HNSRequest -{ - param - ( - [ValidateSet('GET', 'POST', 'DELETE')] - [parameter(Mandatory=$true)] [string] $Method, - [ValidateSet('networks', 'endpoints', 'activities', 'policylists', 'endpointstats', 'plugins')] - [parameter(Mandatory=$true)] [string] $Type, - [parameter(Mandatory=$false)] [string] $Action = $null, - [parameter(Mandatory=$false)] [string] $Data = $null, - [parameter(Mandatory=$false)] [Guid] $Id = [Guid]::Empty - ) - - $hnsPath = "/$Type" - - if ($id -ne [Guid]::Empty) - { - $hnsPath += "/$id"; - } - - if ($Action) - { - $hnsPath += "/$Action"; - } - - $request = ""; - if ($Data) - { - $request = $Data - } - - $output = ""; - $response = ""; - Write-Verbose "Invoke-HNSRequest Method[$Method] Path[$hnsPath] Data[$request]" - - $hnsApi = Get-VmComputeNativeMethods - $hnsApi::HNSCall($Method, $hnsPath, "$request", [ref] $response); - - Write-Verbose "Result : $response" - if ($response) - { - try { - $output = ($response | ConvertFrom-Json); - } catch { - Write-Error $_.Exception.Message - return "" - } - if ($output.Error) - { - Write-Error $output; - } - $output = $output.Output; - } - - return $output; -} - -######################################################################### - -Export-ModuleMember -Function Get-HNSActivities -Export-ModuleMember -Function Get-HnsSwitchExtensions -Export-ModuleMember -Function Set-HnsSwitchExtension - -Export-ModuleMember -Function New-HNSNetwork - -Export-ModuleMember -Function New-HNSEndpoint -Export-ModuleMember -Function New-HnsRemoteEndpoint - -Export-ModuleMember -Function Attach-HNSHostEndpoint -Export-ModuleMember -Function Attach-HNSVMEndpoint -Export-ModuleMember -Function Attach-HNSEndpoint -Export-ModuleMember -Function Detach-HNSHostEndpoint -Export-ModuleMember -Function Detach-HNSVMEndpoint -Export-ModuleMember -Function Detach-HNSEndpoint - -Export-ModuleMember -Function Get-HNSPolicyList -Export-ModuleMember -Function Remove-HnsPolicyList -Export-ModuleMember -Function New-HnsRoute -Export-ModuleMember -Function New-HnsLoadBalancer - -Export-ModuleMember -Function Invoke-HNSRequest diff --git a/kubeadm/kube-proxy/Dockerfile b/kubeadm/kube-proxy/Dockerfile index e72a8b34..8707c11c 100644 --- a/kubeadm/kube-proxy/Dockerfile +++ b/kubeadm/kube-proxy/Dockerfile @@ -1,16 +1,22 @@ -ARG k8sVersion="v1.17.3" -ARG servercoreTag="ltsc2019" - -FROM mcr.microsoft.com/windows/servercore:${servercoreTag} -SHELL ["powershell", "-NoLogo", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] +ARG BASE="mcr.microsoft.com/powershell:nanoserver-1809" +ARG k8sVersion="v1.19.3" +FROM --platform=linux/amd64 curlimages/curl as bins ARG k8sVersion -RUN mkdir -force C:\k\kube-proxy; \ - pushd C:\k\kube-proxy; \ - curl.exe -sLO https://dl.k8s.io/${env:k8sVersion}/bin/windows/amd64/kube-proxy.exe +WORKDIR /utils +RUN curl -Lo wins.exe https://github.com/rancher/wins/releases/download/v0.0.4/wins.exe +RUN curl -Lo yq.exe https://github.com/mikefarah/yq/releases/download/2.4.1/yq_windows_amd64.exe + +WORKDIR /kube-proxy +RUN curl -sLO https://dl.k8s.io/${k8sVersion}/bin/windows/amd64/kube-proxy.exe + +FROM $BASE + +ENV PATH="C:\Program Files\PowerShell;C:\utils;C:\Windows\system32;C:\Windows;" + +# wins.exe doesn't work in nanoserver with default ContainerUser. +USER ContainerAdministrator -RUN mkdir C:\utils; \ - curl.exe -sLo C:\utils\wins.exe https://github.com/rancher/wins/releases/download/v0.0.4/wins.exe; \ - curl.exe -sLo C:\utils\yq.exe https://github.com/mikefarah/yq/releases/download/2.4.1/yq_windows_amd64.exe; \ - "[Environment]::SetEnvironmentVariable('PATH', $env:PATH + ';C:\utils', [EnvironmentVariableTarget]::Machine)" +COPY --from=bins /utils /utils +COPY --from=bins /kube-proxy /k/kube-proxy diff --git a/kubeadm/kube-proxy/build.ps1 b/kubeadm/kube-proxy/build.ps1 new file mode 100644 index 00000000..7257004f --- /dev/null +++ b/kubeadm/kube-proxy/build.ps1 @@ -0,0 +1,56 @@ +param( + [string]$image = "sigwindowstools/kube-proxy", + [switch]$push, + [version]$minVersion = "1.17.0" +) + +$output="docker" +if ($push.IsPresent) { + $output="registry" +} + +Import-Module "../buildx.psm1" +Set-Builder + +function Build-KubeProxy([string]$version) +{ + $config = Get-Content ".\buildconfig.json" | ConvertFrom-Json + + [string[]]$items = @() + [string[]]$bases = @() + foreach($tag in $config.tagsMap) + { + $base = "$($config.baseimage):$($tag.source)" + $current = "$($image):$($version)-$($tag.target)" + $bases += $base + $items += $current + New-Build -name $current -output $output -args @("BASE=$base", "k8sVersion=$version") + } + + if ($push.IsPresent) + { + Push-Manifest -name "$($image):$version-nanoserver" -items $items -bases $bases + } +} + +$versions = (curl -L k8s.gcr.io/v2/kube-proxy/tags/list | ConvertFrom-Json).tags +foreach($version in $versions) +{ + if ($version -match "^v(\d+\.\d+\.\d+)$") + { + $testVersion = [version]$Matches[1] + if ($testVersion -ge $minVersion) + { + Write-Host "Build $($image):$($version)" + Build-KubeProxy -version $version + } + else + { + Write-Host "Skip $version because it less than $minVersion." + } + } + else + { + Write-Host "Skip $version because it isn't release version." + } +} diff --git a/kubeadm/kube-proxy/buildconfig.json b/kubeadm/kube-proxy/buildconfig.json new file mode 100644 index 00000000..7a303274 --- /dev/null +++ b/kubeadm/kube-proxy/buildconfig.json @@ -0,0 +1,9 @@ +{ + "baseimage": "mcr.microsoft.com/powershell", + "tagsMap":[ + {"source":"nanoserver-2004","target":"2004"}, + {"source":"nanoserver-1909","target":"1909"}, + {"source":"nanoserver-1903","target":"1903"}, + {"source":"nanoserver-1809","target":"1809"} + ] +} \ No newline at end of file diff --git a/kubeadm/kube-proxy/kube-proxy.yml b/kubeadm/kube-proxy/kube-proxy.yml index 84e60cde..25efa9ab 100644 --- a/kubeadm/kube-proxy/kube-proxy.yml +++ b/kubeadm/kube-proxy/kube-proxy.yml @@ -76,7 +76,7 @@ spec: serviceAccountName: kube-proxy containers: - command: - - powershell + - pwsh args: - -file - /var/lib/kube-proxy-windows/run-script.ps1 @@ -90,7 +90,7 @@ spec: valueFrom: fieldRef: fieldPath: status.podIP - image: sigwindowstools/kube-proxy:VERSION + image: sigwindowstools/kube-proxy:VERSION-nanoserver name: kube-proxy volumeMounts: - name: host