Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GA support for Windows hostprocess containers #7857

Merged
merged 16 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ crypto/tmp
hack/release/release
node/windows-packaging/CalicoWindows/confd/config-bgp.ps1
node/windows-packaging/CalicoWindows/confd/config-bgp.psm1
node/windows-packaging/nssm.zip
_output
builder.coverprofile
hack/release/ghr
Expand Down
13 changes: 9 additions & 4 deletions apiserver/cmd/apiserver/server/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import (
"os"
"time"

"github.com/projectcalico/calico/libcalico-go/lib/winutils"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/clientcmd"
)

const (
Expand All @@ -30,10 +29,16 @@ func WatchExtensionAuth(stopChan chan struct{}) (bool, error) {
// set up k8s client
// attempt 1: KUBECONFIG env var
cfgFile := os.Getenv("KUBECONFIG")
cfg, err := clientcmd.BuildConfigFromFlags("", cfgFile)
// Host env vars may override the container on Windows HPC, so $env:KUBECONFIG cannot
// be trusted in this case
// FIXME: this will no longer be needed when containerd v1.6 is EOL'd
if winutils.InHostProcessContainer() {
cfgFile = ""
}
cfg, err := winutils.BuildConfigFromFlags("", cfgFile)
if err != nil {
// attempt 2: in cluster config
if cfg, err = rest.InClusterConfig(); err != nil {
if cfg, err = winutils.GetInClusterConfig(); err != nil {
mgleung marked this conversation as resolved.
Show resolved Hide resolved
return false, err
}
}
Expand Down
39 changes: 39 additions & 0 deletions cni-plugin/Dockerfile-windows
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (c) 2023 Tigera, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# FIXME: Use WINDOWS_HPC_VERSION and image instead of nanoserver and WINDOWS_VERSIONS when containerd v1.6 is EOL'd
# ARG WINDOWS_HPC_VERSION
ARG WINDOWS_VERSION

# FROM mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:${WINDOWS_HPC_VERSION}
FROM mcr.microsoft.com/windows/nanoserver:${WINDOWS_VERSION}

ARG GIT_VERSION=unknown

LABEL name="Calico Networking for CNI" \
vendor="Project Calico" \
version=$GIT_VERSION \
release="1" \
summary="Calico Networking for CNI" \
description="Calico Networking for CNI includes a CNI networking plugin and CNI IPAM plugin" \
maintainer="[email protected]"

ADD licenses/ /licenses
ADD LICENSE /licenses/

ADD bin/windows/ /opt/cni/bin/

ENV PATH=$PATH;/opt/cni/bin
WORKDIR /opt/cni/bin
CMD ["/opt/cni/bin/install.exe"]
116 changes: 100 additions & 16 deletions cni-plugin/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ LOCAL_CHECKS=check-boring-ssl
# Name of the images.
# e.g., <registry>/<name>:<tag>
CNI_PLUGIN_IMAGE ?=cni
CNI_PLUGIN_IMAGE_WINDOWS ?=cni-windows
BUILD_IMAGES ?=$(CNI_PLUGIN_IMAGE)

###############################################################################
Expand Down Expand Up @@ -55,23 +56,28 @@ BIN=bin/$(ARCH)
DEPLOY_CONTAINER_MARKER=$(DEPLOY_CONTAINER_STATIC_MARKER)
endif

.PHONY: clean
clean:
.PHONY: clean clean-windows
clean: clean-windows
# Clean .created files which indicate images / releases have been built.
find . -name '.*.created*' -type f -delete
find . -name '.*.published*' -type f -delete
rm -rf $(BIN) bin $(DEPLOY_CONTAINER_MARKER) .go-pkg-cache pkg/install/install.test
rm -rf $(BIN) bin $(DEPLOY_CONTAINER_MARKER) .go-pkg-cache pkg/install/install.test
rm -f *.created
rm -rf config/
rm -rf dist/

clean-windows: clean-windows-builder
rm -rf $(WINDOWS_BIN) $(WINDOWS_DIST)

###############################################################################
# Building the binary
###############################################################################
.PHONY: build
build: $(BIN)/install $(BIN)/calico $(BIN)/calico-ipam
ifeq ($(ARCH),amd64)
# Go only supports amd64 for Windows builds.
BIN_WIN=bin/windows
build: $(BIN_WIN)/calico.exe $(BIN_WIN)/calico-ipam.exe
WINDOWS_BIN=bin/windows
build: $(WINDOWS_BIN)/install.exe $(WINDOWS_BIN)/calico.exe $(WINDOWS_BIN)/calico-ipam.exe
endif
# If ARCH is arm based, find the requested version/variant
ifeq ($(word 1,$(subst v, ,$(ARCH))),arm)
Expand All @@ -97,20 +103,23 @@ else
endif

## Build the Calico network plugin and ipam plugins for Windows
$(BIN_WIN)/calico.exe $(BIN_WIN)/calico-ipam.exe: $(SRC_FILES)
$(WINDOWS_BIN)/install.exe: $(SRC_FILES)
-mkdir -p $(WINDOWS_BIN)
$(DOCKER_RUN) \
-e GOOS=windows \
-e GOARCH=amd64 \
-e CGO_ENABLED=1 \
$(CALICO_BUILD) sh -c '$(GIT_CONFIG_SSH) \
go build -v -buildvcs=false -o $(BIN_WIN)/calico.exe -ldflags "$(LDFLAGS)" $(PACKAGE_NAME)/cmd/calico && \
go build -v -buildvcs=false -o $(BIN_WIN)/calico-ipam.exe -ldflags "$(LDFLAGS)" $(PACKAGE_NAME)/cmd/calico'
$(CALICO_BUILD) sh -c '$(GIT_CONFIG_SSH) \
go build -v -buildvcs=false -o $(WINDOWS_BIN)/install.exe -ldflags "$(LDFLAGS)" $(PACKAGE_NAME)/cmd/calico'

$(WINDOWS_BIN)/calico-ipam.exe $(WINDOWS_BIN)/calico.exe: $(WINDOWS_BIN)/install.exe
cp "$<" "$@"

###############################################################################
# Building the image
###############################################################################
image: $(DEPLOY_CONTAINER_MARKER)
image-all: $(addprefix sub-image-,$(VALIDARCHES)) sub-image-fips-amd64
image-all: $(addprefix sub-image-,$(VALIDARCHES)) sub-image-fips-amd64 image-windows
sub-image-%:
$(MAKE) image ARCH=$*
sub-image-fips-%:
Expand All @@ -128,17 +137,23 @@ $(DEPLOY_CONTAINER_FIPS_MARKER): Dockerfile.$(ARCH) build fetch-cni-bins
$(MAKE) retag-build-images-with-registries VALIDARCHES=$(ARCH) IMAGETAG=latest-fips LATEST_IMAGE_TAG=latest-fips
touch $@

.PHONY: fetch-cni-bins
.PHONY: fetch-cni-bins fetch-win-cni-bins
fetch-cni-bins: $(BIN)/flannel $(BIN)/loopback $(BIN)/host-local $(BIN)/portmap $(BIN)/tuning $(BIN)/bandwidth
fetch-win-cni-bins: $(WINDOWS_BIN)/flannel.exe

$(BIN)/loopback $(BIN)/host-local $(BIN)/portmap $(BIN)/tuning $(BIN)/bandwidth:
mkdir -p $(BIN)
-mkdir -p $(BIN)
$(CURL) -L --retry 5 $(CNI_ARTIFACTS_URL)/$(CNI_VERSION)/cni-plugins-linux-$(subst v7,,$(ARCH))-$(CNI_VERSION).tgz | tar -xz -C $(BIN) ./loopback ./host-local ./portmap ./tuning ./bandwidth

$(BIN)/flannel:
mkdir -p $(BIN)
-mkdir -p $(BIN)
$(CURL) -L --retry 5 https://github.com/flannel-io/cni-plugin/releases/download/$(FLANNEL_VERSION)/cni-plugin-flannel-linux-$(subst v7,,$(ARCH))-$(FLANNEL_VERSION).tgz | tar -xz -C $(BIN) ./flannel-$(subst v7,,$(ARCH))
mv $(BIN)/flannel-$(subst v7,,$(ARCH)) $(BIN)/flannel
mv $(BIN)/flannel-$(subst v7,,$(ARCH)) $@

$(WINDOWS_BIN)/flannel.exe:
-mkdir -p $(WINDOWS_BIN)
$(CURL) -L --retry 5 https://github.com/flannel-io/cni-plugin/releases/download/$(FLANNEL_VERSION)/cni-plugin-flannel-windows-amd64-$(FLANNEL_VERSION).tgz | tar -xz -C $(WINDOWS_BIN) ./flannel-amd64.exe
mv $(WINDOWS_BIN)/flannel-amd64.exe $@

###############################################################################
# Unit Tests
Expand Down Expand Up @@ -223,8 +238,8 @@ ci: clean mod-download build static-checks test-cni-versions image-all test-inst
cd: image-all cd-common

## Build fv binary for Windows
$(BIN_WIN)/win-fv.exe: $(WINFV_SRCFILES)
$(DOCKER_RUN) -e GOOS=windows $(CALICO_BUILD) sh -c '$(GIT_CONFIG_SSH) go test ./win_tests -c -o $(BIN_WIN)/win-fv.exe'
$(WINDOWS_BIN)/win-fv.exe: $(WINFV_SRCFILES)
$(DOCKER_RUN) -e GOOS=windows $(CALICO_BUILD) sh -c '$(GIT_CONFIG_SSH) go test ./win_tests -c -o $(WINDOWS_BIN)/win-fv.exe'

###############################################################################
# Release
Expand Down Expand Up @@ -278,6 +293,75 @@ release-publish-latest: release-prereqs

$(MAKE) push-images-to-registries push-manifests RELEASE=true IMAGETAG=latest RELEASE=$(RELEASE) CONFIRM=$(CONFIRM)

# FIXME: Use WINDOWS_HPC_VERSION and image instead of nanoserver and WINDOWS_VERSIONS when containerd v1.6 is EOL'd
# .PHONY: image-windows release-windows
# # Build Windows image and possibly push it to $DEV_REGISTRIES
# image-windows: setup-windows-builder Dockerfile-windows build fetch-win-cni-bins
# push="$${PUSH:-false}"; \
# image_version="$${VERSION:-latest}"; \
# for registry in $(DEV_REGISTRIES); do \
# echo Building and pushing Windows image to $${registry}; \
# image="$${registry}/$(CNI_PLUGIN_IMAGE_WINDOWS):$${image_version}"; \
# docker buildx build \
# --platform windows/amd64 \
# --output=type=image,push=$${push} \
# -t $${image} \
# --pull \
# --no-cache \
# --build-arg GIT_VERSION=$(GIT_VERSION) \
# --build-arg WINDOWS_HPC_VERSION=$(WINDOWS_HPC_VERSION) \
# -f Dockerfile-windows .; \
# done ;

# # Build and push Windows image
# release-windows: release-prereqs clean-windows
# $(MAKE) image-windows PUSH=true

WINDOWS_DIST = dist/windows

$(WINDOWS_DIST)/$(CNI_PLUGIN_IMAGE_WINDOWS)-$(GIT_VERSION)-%.tar: sub-image-windows-$*

sub-image-windows-%: setup-windows-builder Dockerfile-windows build fetch-win-cni-bins
# ensure dir for windows image tars exits
-mkdir -p $(WINDOWS_DIST)
docker buildx build \
--platform windows/amd64 \
--output=type=docker,dest=$(CURDIR)/$(WINDOWS_DIST)/$(CNI_PLUGIN_IMAGE_WINDOWS)-$(GIT_VERSION)-$*.tar \
--pull \
-t $(CNI_PLUGIN_IMAGE_WINDOWS):latest \
--build-arg GIT_VERSION=$(GIT_VERSION) \
--build-arg=WINDOWS_VERSION=$* \
-f Dockerfile-windows .

.PHONY: image-windows release-windows
image-windows: setup-windows-builder
for version in $(WINDOWS_VERSIONS); do \
$(MAKE) sub-image-windows-$${version}; \
done;

release-windows: clean-windows image-windows
image_version="$${VERSION:-latest}"; \
for registry in $(DEV_REGISTRIES); do \
echo Pushing Windows images to $${registry}; \
all_images=""; \
manifest_image="$${registry}/$(CNI_PLUGIN_IMAGE_WINDOWS):$${image_version}"; \
for win_ver in $(WINDOWS_VERSIONS); do \
image_tar="$(WINDOWS_DIST)/$(CNI_PLUGIN_IMAGE_WINDOWS)-$(GIT_VERSION)-$${win_ver}.tar"; \
image="$${registry}/$(CNI_PLUGIN_IMAGE_WINDOWS):$${image_version}-windows-$${win_ver}"; \
echo Pushing image $${image} ...; \
$(CRANE_BINDMOUNT) push $${image_tar} $${image}$(double_quote) & \
all_images="$${all_images} $${image}"; \
done; \
wait; \
$(DOCKER_MANIFEST) create --amend $${manifest_image} $${all_images}; \
for win_ver in $(WINDOWS_VERSIONS); do \
version=$$(docker manifest inspect mcr.microsoft.com/windows/nanoserver:$${win_ver} | grep "os.version" | head -n 1 | awk -F\" '{print $$4}'); \
image="$${registry}/$(CNI_PLUGIN_IMAGE_WINDOWS):$${image_version}-windows-$${win_ver}"; \
$(DOCKER_MANIFEST) annotate --os windows --arch amd64 --os-version $${version} $${manifest_image} $${image}; \
done; \
$(DOCKER_MANIFEST) push --purge $${manifest_image}; \
done ;

###############################################################################
# Developer helper scripts (not used by build or test)
###############################################################################
Expand Down
2 changes: 1 addition & 1 deletion cni-plugin/cmd/calico/calico.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func main() {
plugin.Main(VERSION)
case "calico-ipam", "calico-ipam.exe":
ipamplugin.Main(VERSION)
case "install":
case "install", "install.exe":
err := install.Install()
if err != nil {
logrus.WithError(err).Fatal("Error installing CNI plugin")
Expand Down
Loading