Skip to content
Open
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
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,18 @@ 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-push-imagelist
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
Expand Down
4 changes: 4 additions & 0 deletions backend/aks/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions backend/caasp4os/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's basically moving module-experimental-airgap-up here right?
I'm okay with doing that in a follow-up PR, but I expect by the time this whole thing is done we'll drop the experimental version?

Shouldn't the top-level makefile have a

airgap-up airgap-down:
	$(MAKE) -C backend/$(BACKEND) $@

4 changes: 4 additions & 0 deletions backend/ekcp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions backend/eks/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 8 additions & 0 deletions backend/gke/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 9 additions & 0 deletions backend/gke/airgap-down.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

. ./defaults.sh
. ../../include/common.sh
. .envrc

export KUBECF_NAMESPACE=scf

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to make this configurable (mostly because currently the namespace on GitHub CI is kubecf, because it's just using make kubecf-apply).

Of course, this will all change once RFD9 is in place.

export QUARKS_NAMESPACE=cf-operator
gke_isolate_network 0
14 changes: 14 additions & 0 deletions backend/gke/airgap-up.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

. ./defaults.sh
. ../../include/common.sh
. .envrc

export KUBECF_NAMESPACE=scf

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto. Literally ditto

export QUARKS_NAMESPACE=cf-operator
for ns in $KUBECF_NAMESPACE $QUARKS_NAMESPACE default; do
kubectl create namespace $ns || true

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kubectl create namespace "${ns}" --dry-run=client  -o yaml | kubectl apply -f -

… now that I've typed it out that's just overly verbose and doesn't really help much, does it? I guess it catches errors other than the namespace already existing, but then we'll fail when we label it anyway. Nevermind, then.

kubectl label namespaces --overwrite $ns airgap=true
done

gke_isolate_network 1
4 changes: 4 additions & 0 deletions backend/kind/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions backend/minikube/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
137 changes: 137 additions & 0 deletions include/func.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really seeing what's GKE-specific about this section.

Also, if it is, it seems like it should live in backends/gke/… instead?

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")"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we can do

Suggested change
echo "$(blue "Configure cluster network: Deny egress external")"
printf "%s\n" "$(blue "Configure cluster network: Deny egress external")"

# enable isolation
# ingress - allows all incoming traffic

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't appear to match what we're allowing below.

# 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I don't think we have plans for a drone setup any longer.


cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: airgap-quarks
namespace: ${QUARKS_NAMESPACE}
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 10.0.0.0/8

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we document why we need ingress from this? Is this for Kubernetes to talk to us (because we're a webhook)?

- namespaceSelector: {}
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/8
- namespaceSelector: {}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: airgap-kubecf
namespace: ${KUBECF_NAMESPACE}
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 10.0.0.0/8
- namespaceSelector: {}
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/8
- namespaceSelector: {}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: dnsoutbound-quarks
namespace: ${QUARKS_NAMESPACE}
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- ports:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need a separate policy? Can this not live in airgap-quarks?

- port: 53
protocol: UDP
- port: 53
protocol: TCP
- to:
- namespaceSelector: {}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: dnsoutbound-kubecf
namespace: ${KUBECF_NAMESPACE}
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
- to:
- namespaceSelector: {}
EOF
# For debugging, show what kube thinks of it.
kubectl describe networkpolicies \
--namespace "${QUARKS_NAMESPACE}" \
airgap-quarks
kubectl describe networkpolicies \
--namespace "${KUBECF_NAMESPACE}" \
airgap-kubecf

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent indenting.

Would a kubectl get networkpolicies --all-namespaces --output=wide be useful?

kubectl describe networkpolicies \
--namespace "${QUARKS_NAMESPACE}" \
dnsoutbound-quarks
kubectl describe networkpolicies \
--namespace "${KUBECF_NAMESPACE}" \
dnsoutbound-kubecf
else
# shellcheck disable=SC2005
echo "$(blue "Configure cluster network: Full access")"
# disable isolation
kubectl delete networkpolicies \
--namespace "${KUBECF_NAMESPACE}" \
--ignore-not-found \
airgap-kubecf dnsoutbound-kubecf
kubectl delete networkpolicies \
--namespace "${QUARKS_NAMESPACE}" \
--ignore-not-found \
airgap-quarks dnsoutbound-quarks
fi
}
14 changes: 13 additions & 1 deletion modules/experimental/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@ eirini_release:
eirinifs:
./eirinifs.sh

.PHONY: local-registry
local-registry:
./local-registry.sh

.PHONY: push-imagelist
push-imagelist:
./push-imagelist.sh

.PHONY: podman-imagelist
podman-imagelist:
./podman-imagelist.sh

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it's unclear to me why we have two versions.


.PHONY: airgap-up
airgap-up: airgap-down
airgap-up:
./airgap_up.sh

PHONY: airgap-down
Expand Down
7 changes: 7 additions & 0 deletions modules/experimental/airgap_down.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, that probably should be quoted, because I don't think $/ was supposed to expand here. But then, why do we need that anyway, instead of ssh "sles@${kube_node}" -- sudo …? Something to do with how sudo is working?

Do you have an example of the CRIO_OPTIONS line we're supposed to be changing? It feels like filtering out the --insecure-registry=… bit would be better than just blindly chopping off anything at the end…

If we have perl around, we might be able to get away with

sudo perl -pi -e 's@^CRIO_OPTIONS\s*=.*\K"--insecure-registry=${DOCKER_REGISTRY}"@@' /etc/sysconfig/crio

(In which we we do not want to quote the EOF.)

Side note, do we need to quote ${kube_node} on line 40 (for whitespace etc.)?

sudo sed 's/^\(CRIO_OPTIONS\s*=\s*\).*$/\1""/' \
/etc/sysconfig/crio
EOF
}

Expand Down
16 changes: 16 additions & 0 deletions modules/experimental/airgap_up.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ if [[ ${BACKEND} != "caasp4os" ]]; then
exit 1
fi

DOCKER_REGISTRY=registry.scf.svc.cluster.local

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this always .cluster.local?


airgap_up_node() {
local kube_node host_ip
kube_node=$1
Expand All @@ -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}"/' \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're wiping any existing options?

/etc/sysconfig/crio
EOF
}

Expand All @@ -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"

5 changes: 5 additions & 0 deletions modules/experimental/docker/Dockerfile.skopeo
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM opensuse/leap:latest
LABEL MAINTAINER="Víctor Cuadrado Juan <vcuadradojuan@suse.com>, Christian Richter <crichter@suse.com>"
RUN zypper ref \
&& zypper in -y --no-recommends skopeo \
&& zypper clean --all

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: New line at EOF

66 changes: 66 additions & 0 deletions modules/experimental/local-registry.sh
Original file line number Diff line number Diff line change
@@ -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 - <<HEREDOC
---
# PVC for local registry service
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: registry-data-pvc
labels:
app: local-registry
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 30Gi
---
# Docker registry pod definition
apiVersion: v1
kind: Pod
metadata:
name: local-registry
labels:
app: local-registry
namespace: default
spec:
volumes:
- name: registry-data-vol
persistentVolumeClaim:
claimName: registry-data-pvc
containers:
- name: local-registry
image: registry:2
imagePullPolicy: Always
ports:
- containerPort: 5000
volumeMounts:
- mountPath: /var/lib/registry
name: registry-data-vol
---
# Registry service definition
kind: Service
apiVersion: v1
metadata:
name: local-registry
namespace: default
spec:
selector:
app: local-registry
ports:
- port: 80
targetPort: 5000
HEREDOC

wait_ns default

ok "Registry created"
kubectl get services local-registry -n default
Loading