From 614083e1be66479c11f39af4e5ab75fb3d9eacbf Mon Sep 17 00:00:00 2001 From: Tim Hardeck Date: Thu, 5 Nov 2020 10:40:50 +0100 Subject: [PATCH 1/8] Add module-experimental-local-registry target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This deploys a Docker Registry v2 image. Registry is exposed in local-registry.default.svc.cluster.local and it is set up with a pvc. Signed-off-by: Víctor Cuadrado Juan --- Makefile | 4 ++ modules/experimental/Makefile | 4 ++ modules/experimental/local-registry.sh | 66 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100755 modules/experimental/local-registry.sh diff --git a/Makefile b/Makefile index dea07b5d..6e888003 100644 --- a/Makefile +++ b/Makefile @@ -173,6 +173,10 @@ module-experimental-eirinifs: module-experimental-eirini_release: $(MAKE) -C modules/experimental eirini_release +.PHONY: module-experimental-local-registry +module-experimental-local-registry: + $(MAKE) -C modules/experimental local-registry + .PHONY: module-experimental-airgap-up module-experimental-airgap-up: $(MAKE) -C modules/experimental airgap-up diff --git a/modules/experimental/Makefile b/modules/experimental/Makefile index 5956e482..c2514b19 100644 --- a/modules/experimental/Makefile +++ b/modules/experimental/Makefile @@ -9,6 +9,10 @@ eirini_release: eirinifs: ./eirinifs.sh +.PHONY: local-registry +local-registry: + ./local-registry.sh + .PHONY: airgap-up airgap-up: airgap-down ./airgap_up.sh diff --git a/modules/experimental/local-registry.sh b/modules/experimental/local-registry.sh new file mode 100755 index 00000000..e629bf22 --- /dev/null +++ b/modules/experimental/local-registry.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +. ./defaults.sh +. ../../include/common.sh +. .envrc + +info "Creating local registry at local-registry.default.svc.cluster.local…" + +kubectl apply -f - < Date: Thu, 5 Nov 2020 10:42:57 +0100 Subject: [PATCH 2/8] Add a module-experimental-push-imagelist target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This target parses all imagelist.txt files inside the buildfolder. For each image listed in the files, it spawns a kube job that uses `skopeo copy` to copy the image to the local repository. The target waits for all jobs to have succeeded. We are using dragonchaser/opensuse-skopeo:latest image, which contains podman (with vfs for unpriviliged containers), and skopeo. The kube jobs are configured to retry for 4 times, in case the jobs fail (they may, as all the jobs start at the same time, and my clog the cluster). Signed-off-by: Víctor Cuadrado Juan --- Makefile | 4 ++ modules/experimental/Makefile | 4 ++ modules/experimental/push-imagelist.sh | 62 ++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100755 modules/experimental/push-imagelist.sh diff --git a/Makefile b/Makefile index 6e888003..fb4b0cdc 100644 --- a/Makefile +++ b/Makefile @@ -177,6 +177,10 @@ module-experimental-eirini_release: module-experimental-local-registry: $(MAKE) -C modules/experimental local-registry +.PHONY: module-experimental-push-imagelist +module-experimental-push-imagelist: + $(MAKE) -C modules/experimental push-imagelist + .PHONY: module-experimental-airgap-up module-experimental-airgap-up: $(MAKE) -C modules/experimental airgap-up diff --git a/modules/experimental/Makefile b/modules/experimental/Makefile index c2514b19..af34e9fc 100644 --- a/modules/experimental/Makefile +++ b/modules/experimental/Makefile @@ -13,6 +13,10 @@ eirinifs: local-registry: ./local-registry.sh +.PHONY: push-imagelist +push-imagelist: + ./push-imagelist.sh + .PHONY: airgap-up airgap-up: airgap-down ./airgap_up.sh diff --git a/modules/experimental/push-imagelist.sh b/modules/experimental/push-imagelist.sh new file mode 100755 index 00000000..36d3baaa --- /dev/null +++ b/modules/experimental/push-imagelist.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +. ./defaults.sh +. ../../include/common.sh +. .envrc + +info "Pushing all imagelist.txt images to local-registry.default.svc.cluster.local" + +kubectl create namespace push-imagelist 2>/dev/null || true + +# POSIX compliant: +while IFS= read -r imagelist_file +do + # Create a kube job per image in imagelist.txt. There, pull it, retag it, + # and push the image to the local registry + for SOURCE_IMAGE in $(cat "$imagelist_file"); do + JOB_NAME=${SOURCE_IMAGE%%\:*} # remove suffix after ':' + JOB_NAME=${JOB_NAME////-} # substitute '/' with '-' + JOB_NAME=${JOB_NAME:0:63} # truncate to 63 charts for kubernetes + TARGET_REGISTRY='local-registry.default.svc.cluster.local' + kubectl apply --overwrite=false -f - <> /etc/containers/registries.conf + echo '[registries.Insecure]' >> /etc/containers/registries.conf + echo "registries = ['${TARGET_REGISTRY}']" >> /etc/containers/registries.conf + + # add registry.suse.com/cap/ in front if it's not already there + if [[ $( echo "$SOURCE_IMAGE" | grep -o '/' | tr -d '\r\n' | wc -c) -lt 1 ]]; then + # SOURCE_IMAGE=docker.io/"$SOURCE_IMAGE" # upstream + SOURCE_IMAGE=registry.suse.com/cap/$SOURCE_IMAGE # cap + fi + + org=\$(echo \$SOURCE_IMAGE | cut -d/ -f2) + image=\$(echo \$SOURCE_IMAGE | cut -d/ -f3) + + echo "Mirroring image \$SOURCE_IMAGE to ${TARGET_REGISTRY}" + skopeo copy "docker://\${SOURCE_IMAGE}" "docker://${TARGET_REGISTRY}/\$org/\$image" + echo "Mirrored image \$SOURCE_IMAGE in ${TARGET_REGISTRY}" + restartPolicy: Never + backoffLimit: 4 +HEREDOC + done +done < <(find . -name "imagelist.txt") + +info "Waiting for jobs to finish pushing images…" +kubectl -n push-imagelist wait --for=condition=complete job --all --timeout=-1s + +ok "All images pushed to local-registry.default.svc.cluster.local" From 9ab51ad49ea0b305469f7029c75b4c5ee2a2d0e6 Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 5 Nov 2020 11:09:10 +0100 Subject: [PATCH 3/8] Move isolate_network() to gke_isolate_network() in include/func.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Cuadrado Juan --- include/func.sh | 137 +++++++++++++++++++++++++++++++++++ modules/tests/kubecf-test.sh | 70 +----------------- 2 files changed, 139 insertions(+), 68 deletions(-) diff --git a/include/func.sh b/include/func.sh index 5ab11125..4a3da5ec 100644 --- a/include/func.sh +++ b/include/func.sh @@ -375,3 +375,140 @@ wait_for_cf-operator() { wait_for "kubectl delete -f ../kube/cf-operator/qstatefulset_tolerations.yaml --namespace=scf" fi } + + +gke_isolate_network() { + enable="${1:-1}" + + if [[ $enable == 1 ]]; then + # Complaint wrong. The echo generates a traling newline the `blue` doesn't. + # shellcheck disable=SC2005 + echo "$(blue "Configure cluster network: Deny egress external")" + # enable isolation + # ingress - allows all incoming traffic + # egress - allows dns traffic anywhere + # - allows traffic to all ports, pods, namespaces + # (but no whitelisting of external ips!) + # references + # - BASE = https://github.com/ahmetb/kubernetes-network-policy-recipes + # - (BASE)/blob/master/02a-allow-all-traffic-to-an-application.md + # - (BASE)/blob/master/14-deny-external-egress-traffic.md + # - See also https://www.youtube.com/watch?v=3gGpMmYeEO8 (31min) + # - Egress info wrt disallow external see 17:20-17:52 + # + # __ATTENTION__ + # Requires a networking plugin to enforce, else ignored + # (if not directly supported by platform) + # - Example plugins: Calico, WeaveNet, Romana + # + # GKE: Uses Calico, Use `--enable-network-policy` when + # creating a cluster (`gcloud`). + # Minikube needs special setup. + # KinD used by our Drone setup may have support. + + cat < Date: Thu, 5 Nov 2020 11:13:33 +0100 Subject: [PATCH 4/8] Add airgap-up and airgap-down targets on GKE backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Cuadrado Juan --- backend/gke/Makefile | 8 ++++++++ backend/gke/airgap-down.sh | 9 +++++++++ backend/gke/airgap-up.sh | 14 ++++++++++++++ 3 files changed, 31 insertions(+) create mode 100755 backend/gke/airgap-down.sh create mode 100755 backend/gke/airgap-up.sh diff --git a/backend/gke/Makefile b/backend/gke/Makefile index b0d02c6b..59a0c592 100644 --- a/backend/gke/Makefile +++ b/backend/gke/Makefile @@ -30,3 +30,11 @@ force-clean-cluster: .PHONY: all all: deploy + +.PHONY: airgap-up +airgap-up: + ./airgap-up.sh + +.PHONY: airgap-down +airgap-down: + ./airgap-down.sh diff --git a/backend/gke/airgap-down.sh b/backend/gke/airgap-down.sh new file mode 100755 index 00000000..88b462a6 --- /dev/null +++ b/backend/gke/airgap-down.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +. ./defaults.sh +. ../../include/common.sh +. .envrc + +export KUBECF_NAMESPACE=scf +export QUARKS_NAMESPACE=cf-operator +gke_isolate_network 0 diff --git a/backend/gke/airgap-up.sh b/backend/gke/airgap-up.sh new file mode 100755 index 00000000..458de73f --- /dev/null +++ b/backend/gke/airgap-up.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +. ./defaults.sh +. ../../include/common.sh +. .envrc + +export KUBECF_NAMESPACE=scf +export QUARKS_NAMESPACE=cf-operator +for ns in $KUBECF_NAMESPACE $QUARKS_NAMESPACE default; do + kubectl create namespace $ns || true + kubectl label namespaces --overwrite $ns airgap=true +done + +gke_isolate_network 1 From 44cda0f379e83634b1903ebb38347d163210b0fb Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 5 Nov 2020 11:14:18 +0100 Subject: [PATCH 5/8] Add no-ops for airgap-up and airgap-down targets on rest of backends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Cuadrado Juan --- backend/aks/Makefile | 4 ++++ backend/caasp4os/Makefile | 4 ++++ backend/ekcp/Makefile | 4 ++++ backend/eks/Makefile | 4 ++++ backend/kind/Makefile | 4 ++++ backend/minikube/Makefile | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/backend/aks/Makefile b/backend/aks/Makefile index 682c6b7e..f3c89f11 100644 --- a/backend/aks/Makefile +++ b/backend/aks/Makefile @@ -35,3 +35,7 @@ all:: @echo 'WARNING: stil WIP. Use it on your own risk.' @echo 'Kindly waiting for 5s…'; sleep 5 all:: deploy + +.PHONY: airgap-up airgap-down +airgap-up airgap-down: + echo "Not implemented yet" && exit 1 diff --git a/backend/caasp4os/Makefile b/backend/caasp4os/Makefile index 5cac6a23..199b8dc9 100644 --- a/backend/caasp4os/Makefile +++ b/backend/caasp4os/Makefile @@ -36,3 +36,7 @@ force-clean-cluster: .PHONY: all all: deps-caasp4os caasp4os-deploy caasp-prepare + +.PHONY: airgap-up airgap-down +airgap-up airgap-down: + echo "Not implemented yet" && exit 1 diff --git a/backend/ekcp/Makefile b/backend/ekcp/Makefile index b2d3aefd..4417c910 100644 --- a/backend/ekcp/Makefile +++ b/backend/ekcp/Makefile @@ -36,3 +36,7 @@ force-clean-cluster: .PHONY: all all: up kubeconfig prepare + +.PHONY: airgap-up airgap-down +airgap-up airgap-down: + echo "Not implemented yet" && exit 1 diff --git a/backend/eks/Makefile b/backend/eks/Makefile index 216038e6..b90344a5 100644 --- a/backend/eks/Makefile +++ b/backend/eks/Makefile @@ -32,3 +32,7 @@ force-clean-cluster: .PHONY: all all: deploy + +.PHONY: airgap-up airgap-down +airgap-up airgap-down: + echo "Not implemented yet" && exit 1 diff --git a/backend/kind/Makefile b/backend/kind/Makefile index f3a4a051..89cfa3de 100644 --- a/backend/kind/Makefile +++ b/backend/kind/Makefile @@ -54,3 +54,7 @@ stop: .PHONY: restart restart: ./restart.sh + +.PHONY: airgap-up airgap-down +airgap-up airgap-down: + echo "Not implemented yet" && exit 1 diff --git a/backend/minikube/Makefile b/backend/minikube/Makefile index c4352332..5e4bbee6 100644 --- a/backend/minikube/Makefile +++ b/backend/minikube/Makefile @@ -38,3 +38,7 @@ start: .PHONY: stop stop: ./stop.sh + +.PHONY: airgap-up airgap-down +airgap-up airgap-down: + echo "Not implemented yet" && exit 1 From 92be772c3a5b49bb6ae04cde52fb87345c6cb257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Cuadrado=20Juan?= Date: Thu, 5 Nov 2020 11:16:21 +0100 Subject: [PATCH 6/8] Add a module-experimental-podman-imagelist This is just a test target with a podman image that allows us to do podman pull. Signed-off-by: Christian Richter --- Makefile | 4 ++ modules/experimental/Makefile | 4 ++ modules/experimental/podman-imagelist.sh | 82 ++++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100755 modules/experimental/podman-imagelist.sh diff --git a/Makefile b/Makefile index fb4b0cdc..6cf3d4e8 100644 --- a/Makefile +++ b/Makefile @@ -181,6 +181,10 @@ module-experimental-local-registry: module-experimental-push-imagelist: $(MAKE) -C modules/experimental push-imagelist +.PHONY: module-experimental-podman-imagelist +module-experimental-podman-imagelist: + $(MAKE) -C modules/experimental podman-imagelist + .PHONY: module-experimental-airgap-up module-experimental-airgap-up: $(MAKE) -C modules/experimental airgap-up diff --git a/modules/experimental/Makefile b/modules/experimental/Makefile index af34e9fc..bd6e14d9 100644 --- a/modules/experimental/Makefile +++ b/modules/experimental/Makefile @@ -17,6 +17,10 @@ local-registry: push-imagelist: ./push-imagelist.sh +.PHONY: podman-imagelist +podman-imagelist: + ./podman-imagelist.sh + .PHONY: airgap-up airgap-up: airgap-down ./airgap_up.sh diff --git a/modules/experimental/podman-imagelist.sh b/modules/experimental/podman-imagelist.sh new file mode 100755 index 00000000..a0400e19 --- /dev/null +++ b/modules/experimental/podman-imagelist.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +. ./defaults.sh +. ../../include/common.sh +. .envrc + +info "Starting podman container and copying all imagelist.txt files there" + +KUBECF_NAMESPACE=scf + +# Create pod, waiting +kubectl apply --overwrite=false -f - << HEREDOC +--- +apiVersion: v1 +kind: Pod +metadata: + name: push-imagelist-pod + namespace: scf +spec: + containers: + - name: push-imagelist-pod + image: greyarch/podman + command: + - /bin/sh + - -c + - | + mkdir /tmp/kubecf + mkdir /tmp/cf-operator + echo >> /etc/containers/registries.conf + echo '[registries.Insecure]' >> /etc/containers/registries.conf + echo "registries = ['local-registry.default.svc.cluster.local']" >> /etc/containers/registries.conf + apk add --no-cache skopeo + while true; do sleep 100; done +HEREDOC + +# create push-imagelist.sh script +cat >push-imagelist.sh << 'HEREDOC' +#!/usr/bin/env sh + +set -e + +while IFS= read -r file +do + for SOURCE_IMAGE in $(cat "$imagelist_file"); do + MIRROR='local-registry.default.svc.cluster.local' + echo ">>>>> Mirroring image: ${SOURCE_IMAGE}" + # add registry.suse.com/cap/ in front if it's not already there + if [[ $( echo $SOURCE_IMAGE | grep -o '/' | tr -d '\r\n' | wc -c) -lt 1 ]]; then + # SOURCE_IMAGE=docker.io/"$SOURCE_IMAGE" # upstream + SOURCE_IMAGE=registry.suse.com/cap/$SOURCE_IMAGE # cap + fi + + org=$(echo "$SOURCE_IMAGE" | cut -d/ -f2) + image=$(echo "$SOURCE_IMAGE" | cut -d/ -f3) + + skopeo copy "docker://${SOURCE_IMAGE}" "docker://${MIRROR}/${org}/${image} 2>&1 >/dev/null" & + done +done < <(find . -name "imagelist.txt") + + +wait +echo +echo "Done pushing images" +HEREDOC +chmod +x push-imagelist.sh + +# wait for the pod to be up +sleep 30 + +# copy push-imagelist.sh script +kubectl cp push-imagelist.sh "${KUBECF_NAMESPACE}"/push-imagelist-pod:/tmp/push-imagelist.sh + +# copy all imagelist.txt files +while IFS= read -r imagelist_file +do + kubectl cp -n "${KUBECF_NAMESPACE}" "$imagelist_file" \ + "${KUBECF_NAMESPACE}"/push-imagelist-pod:/tmp/"$imagelist_file" +done < <(find . -name "imagelist.txt") + +# start the script in the pod +# TODO +# for now, just cd tmp; ./push-imagelist.sh From c6bd71843ef6e307b2403f4f0fcc71a35e151a9e Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 5 Nov 2020 11:22:51 +0100 Subject: [PATCH 7/8] Add Dockerfile.skopeo for module-experimental-push-imagelist target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Cuadrado Juan --- modules/experimental/docker/Dockerfile.skopeo | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 modules/experimental/docker/Dockerfile.skopeo diff --git a/modules/experimental/docker/Dockerfile.skopeo b/modules/experimental/docker/Dockerfile.skopeo new file mode 100644 index 00000000..4cf67d45 --- /dev/null +++ b/modules/experimental/docker/Dockerfile.skopeo @@ -0,0 +1,5 @@ +FROM opensuse/leap:latest +LABEL MAINTAINER="Víctor Cuadrado Juan , Christian Richter " +RUN zypper ref \ + && zypper in -y --no-recommends skopeo \ + && zypper clean --all \ No newline at end of file From 0b15fd6a73be37faa9c290d62659b14e6f9716f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Cuadrado=20Juan?= Date: Thu, 5 Nov 2020 11:24:07 +0100 Subject: [PATCH 8/8] Configure insecure registry on old airgap target for CaaSP Also, don't call airgap-down and then airgap-up, when calling the old airgap-up target. --- modules/experimental/Makefile | 2 +- modules/experimental/airgap_down.sh | 7 +++++++ modules/experimental/airgap_up.sh | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/modules/experimental/Makefile b/modules/experimental/Makefile index bd6e14d9..2401d58b 100644 --- a/modules/experimental/Makefile +++ b/modules/experimental/Makefile @@ -22,7 +22,7 @@ podman-imagelist: ./podman-imagelist.sh .PHONY: airgap-up -airgap-up: airgap-down +airgap-up: ./airgap_up.sh PHONY: airgap-down diff --git a/modules/experimental/airgap_down.sh b/modules/experimental/airgap_down.sh index 68455103..38d6b2c0 100755 --- a/modules/experimental/airgap_down.sh +++ b/modules/experimental/airgap_down.sh @@ -33,6 +33,13 @@ sudo -s << 'EOS' echo "Could not remove DROP 0.0.0.0/0 in OUTPUT chain. Skipping other iptable deletions" fi EOS +EOF + + # Remove insecure registry + # shellcheck disable=SC2087 + ssh -T sles@${kube_node} << EOF +sudo sed 's/^\(CRIO_OPTIONS\s*=\s*\).*$/\1""/' \ + /etc/sysconfig/crio EOF } diff --git a/modules/experimental/airgap_up.sh b/modules/experimental/airgap_up.sh index 4470d563..2ce380fc 100755 --- a/modules/experimental/airgap_up.sh +++ b/modules/experimental/airgap_up.sh @@ -9,6 +9,8 @@ if [[ ${BACKEND} != "caasp4os" ]]; then exit 1 fi +DOCKER_REGISTRY=registry.scf.svc.cluster.local + airgap_up_node() { local kube_node host_ip kube_node=$1 @@ -30,6 +32,13 @@ sudo -s << 'EOS' iptables -A OUTPUT -j ACCEPT -d 192.168.0.0/16 iptables -A OUTPUT -j DROP -d 0.0.0.0/0 EOS +EOF + + # Include insecure registry + # shellcheck disable=SC2087 + ssh -T sles@${kube_node} << EOF +sudo sed 's/^\(CRIO_OPTIONS\s*=\s*\).*$/\1"--insecure-registry=${DOCKER_REGISTRY}"/' \ + /etc/sysconfig/crio EOF } @@ -44,5 +53,12 @@ kubectl create namespace scf 2>/dev/null || true kubectl create -n cf-operator -f ../modules/experimental/cilium-block-egress.yaml kubectl create -n scf -f ../modules/experimental/cilium-block-egress.yaml +# # test that indeed it is airgapped: +# if ! kubectl run hello-world --image=hello-world >/dev/null; then +# err "Airgap enabled, but could download an external hello-world container image" +# exit 1 +# fi +# kubectl delete pod hello-world --ignore-not-found + info "Cluster ${CLUSTER_NAME} is now running a simulated airgapped setup. Run \`make module-experimental-airgap-down\` to restore internet access"