1
0
Fork 0

Initial commit.

This commit is contained in:
Sergio Talens-Oliag 2025-05-11 19:56:07 +02:00
commit 840bd2e12a
Signed by: sto
GPG key ID: 821AEE0FD167FBDF
10 changed files with 322 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
dummyhttp-secret.yaml
dummyhttp-sealed-secret.yaml

4
README.md Normal file
View file

@ -0,0 +1,4 @@
# vCluster
This repository contains scripts and templates to test `vcluster` on a `k3d` cluster (we are going to use the one
created for this [post](https://blogops.mixinet.net/posts/gitops/argocd-autopilot/)).

View file

@ -0,0 +1,33 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://forgejo.mixinet.net/blogops/argocd-applications.git//dummyhttp/?ref=dummyhttp-v1.0.0
# Add the config map
configMapGenerator:
- name: dummyhttp-configmap
literals:
- CM_VAR="Vcluster Test Value"
behavior: create
options:
disableNameSuffixHash: true
patches:
# Change the ingress host name
- target:
kind: Ingress
name: dummyhttp
patch: |-
- op: replace
path: /spec/rules/0/host
value: vcluster-dummyhttp.lo.mixinet.net
# Add reloader annotations -- it will only work if we install reloader on the
# virtual cluster, as the one on the host cluster doesn't see the vcluster
# deployment objects
- target:
kind: Deployment
name: dummyhttp
patch: |-
- op: add
path: /metadata/annotations
value:
reloader.stakater.com/auto: "true"
reloader.stakater.com/rollout-strategy: "restart"

View file

@ -0,0 +1,17 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kube-system
resources:
- github.com/stakater/Reloader/deployments/kubernetes/?ref=v1.4.2
patches:
# Add flags to reload workloads when ConfigMaps or Secrets are created or deleted
- target:
kind: Deployment
name: reloader-reloader
patch: |-
- op: add
path: /spec/template/spec/containers/0/args
value:
- '--reload-on-create=true'
- '--reload-on-delete=true'
- '--reload-strategy=annotations'

37
bin/arkade-install.sh Executable file
View file

@ -0,0 +1,37 @@
#!/bin/sh
# TOOLS LIST
ARKADE_APPS="kubectl vcluster"
# Add the arkade binary directory to the path if missing
case ":${PATH}:" in
*:"${HOME}/.arkade/bin":*) ;;
*) export PATH="${PATH}:${HOME}/.arkade/bin" ;;
esac
# Install or update arkade
if command -v arkade >/dev/null; then
echo "Trying to update the arkade application"
sudo arkade update
else
echo "Installing the arkade application"
curl -sLS https://get.arkade.dev | sudo sh
fi
echo ""
echo "Installing tools with arkade"
echo ""
for app in $ARKADE_APPS; do
app_path="$(command -v $app)" || true
if [ "$app_path" ]; then
echo "The application '$app' already available on '$app_path'"
else
arkade get "$app"
fi
done
cat <<EOF
Add the ~/.arkade/bin directory to your PATH if tools have been installed there
EOF

75
bin/create-vcluster.sh Executable file
View file

@ -0,0 +1,75 @@
#!/bin/sh
set -e
# VARIABLES
# Relative PATH to the workdir from the script directory
WORK_DIR_RELPATH="../vcluster"
# Compute WORKDIR
SCRIPT="$(readlink -f "$0")"
SCRIPT_DIR="$(dirname "$SCRIPT")"
WORK_DIR="$(readlink -f "$SCRIPT_DIR/$WORK_DIR_RELPATH")"
# Update the PATH to add the arkade bin directory
# Add the arkade binary directory to the path if missing
case ":${PATH}:" in
*:"${HOME}/.arkade/bin":*) ;;
*) export PATH="${PATH}:${HOME}/.arkade/bin" ;;
esac
# Go to the working directory
cd "$WORK_DIR" || exit 1
echo "=> Creating or updating the vcluster"
vcluster create my-vcluster --namespace my-vcluster --upgrade --connect=false \
--values vcluster.yaml
echo "=> Adding a traefik ingress route tcp to the vcluster api"
kubectl apply -f ingress_route_tcp.yaml
echo "=> Exporting vcluster kubeconfig"
tries="0"
while true; do
if kubectl get -n my-vcluster secret/my-vcluster-kubeconfig >/dev/null 2>&1; then
# Dump the kubeconfig if available
kubectl get -n my-vcluster secret/my-vcluster-kubeconfig \
--template="{{.data.config}}" | base64 -d > ~/.kube/my-vcluster-config
echo "KubeConfig dumped to '~/.kube/my-vcluster-config'"
break
fi
tries="$((tries + 1))"
echo "KubeConfig not avaliable after attempt '$tries'"
if [ "$tries" -lt "10" ]; then
sleep 5
else
break
fi
done
if [ "$tries" -eq "10" ]; then
echo "=> Failed to get the vcluster kubeconfig, try again"
exit 1
fi
cat <<EOF
=> NOTE
Overwrite the KUBECONFIG variable to access the vcluster with 'kubectl':
KUBECONFIG=~/.kube/my-vcluster-config kubectl
You can define the following 'vkubectl' alias to make it easier:
alias vkubectl="KUBECONFIG=~/.kube/my-vcluster-config kubectl"
Or you can merge it with the one on the KUBECONFIG variable and use 'kubectx' or
a similar tool to change the context (for our vcluster the context will be
'my-vcluster_k3d-argocd').
If your KUBECONFIG variable is defined and only has the path to a single file
you can merge it with the vcluster config running the following:
KUBECONFIG="\$KUBECONFIG:~/.kube/my-vcluster-config" \\
kubectl config view --flatten > "\$KUBECONFIG.new";
mv "\$KUBECONFIG.new" "\$KUBECONFIG"
EOF

30
bin/install-vcluster-apps.sh Executable file
View file

@ -0,0 +1,30 @@
#!/bin/sh
set -e
# Applications to install
APPS="dummyhttp reloader"
# Relative PATH to the workdir from the script directory
WORK_DIR_RELPATH="../apps"
# Compute WORKDIR
SCRIPT="$(readlink -f "$0")"
SCRIPT_DIR="$(dirname "$SCRIPT")"
WORK_DIR="$(readlink -f "$SCRIPT_DIR/$WORK_DIR_RELPATH")"
# Update the PATH to add the arkade bin directory
# Add the arkade binary directory to the path if missing
case ":${PATH}:" in
*:"${HOME}/.arkade/bin":*) ;;
*) export PATH="${PATH}:${HOME}/.arkade/bin" ;;
esac
# Go to the working directory
cd "$WORK_DIR" || exit 1
for app in $APPS; do
echo "=> Deploying the '$app' application"
kustomize build "$app" | \
KUBECONFIG=~/.kube/my-vcluster-config kubectl apply -f -
done

View file

@ -0,0 +1,78 @@
#!/bin/sh
set -e
# VARIABLES
SECRET_VALUE="${*:-Vcluster Boo}"
SECRET_CONTEXT="k3d-argocd"
SECRET_NAME="dummyhttp-secret"
SECRET_NAMESPACE="my-vcluster-default"
# Relative PATH to the workdir from the script directory
WORK_DIR_RELPATH="../"
# Compute WORKDIR
SCRIPT="$(readlink -f "$0")"
SCRIPT_DIR="$(dirname "$SCRIPT")"
WORK_DIR="$(readlink -f "$SCRIPT_DIR/$WORK_DIR_RELPATH")"
# Update the PATH to add the arkade bin directory
# Add the arkade binary directory to the path if missing
case ":${PATH}:" in
*:"${HOME}/.arkade/bin":*) ;;
*) export PATH="${PATH}:${HOME}/.arkade/bin" ;;
esac
# Go to the working directory
cd "$WORK_DIR" || exit 1
echo "=> Checking if the '$SECRET_NAMESPACE' is available"
if kubectl get namespace "$SECRET_NAMESPACE" >/dev/null 2>&1; then
echo "The '$SECRET_NAMESPACE' namespace already exists"
else
kubectl create namespace "$SECRET_NAMESPACE"
fi
echo "=> Creating secret file with SECRET_VAR = '$SECRET_VALUE'"
echo -n "$SECRET_VALUE" | \
kubectl create secret generic "$SECRET_NAME" --namespace "$SECRET_NAMESPACE" \
--dry-run=client --from-file=SECRET_VAR=/dev/stdin -o yaml \
>dummyhttp-secret.yaml
echo "=> Creating sealed secret on file"
kubeseal --context "$SECRET_CONTEXT" -f dummyhttp-secret.yaml \
-w dummyhttp-sealed-secret.yaml
rm -f dummyhttp-secret.yaml
echo "=> Adding or updating sealed secret on '$SECRET_NAMESPACE' namespace"
kubectl apply --context "$SECRET_CONTEXT" -f dummyhttp-sealed-secret.yaml
rm -f dummyhttp-sealed-secret.yaml
tries="0"
while true; do
if kubectl get --context "$SECRET_CONTEXT" --namespace "$SECRET_NAMESPACE" \
secret/dummyhttp-secret >/dev/null 2>&1; then
break
fi
tries="$((tries+1))"
echo "Secret not avaliable after attempt '$tries'"
if [ "$tries" -lt "10" ]; then
sleep 2
else
break
fi
done
if [ "$tries" -eq "10" ]; then
echo "Failed to get 'dummyhttp-secret', something dind't work as expected"
exit 1
fi
SECRET_VAR="$(
kubectl get --context "$SECRET_CONTEXT" --namespace "$SECRET_NAMESPACE" \
secret/dummyhttp-secret --template="{{.data.SECRET_VAR}}" | base64 -d
)"
echo "=> Found secret/dummyhttp-secret: SECRET_VAR = '$SECRET_VAR'"

View file

@ -0,0 +1,15 @@
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: my-vcluster-api
namespace: my-vcluster
spec:
entryPoints:
- websecure
routes:
- match: HostSNI(`my-vcluster-api.lo.mixinet.net`)
services:
- name: my-vcluster
port: 443
tls:
passthrough: true

31
vcluster/vcluster.yaml Normal file
View file

@ -0,0 +1,31 @@
controlPlane:
proxy:
# Extra hostnames to sign the vCluster proxy certificate for
extraSANs:
- my-vcluster-api.lo.mixinet.net
exportKubeConfig:
context: my-vcluster_k3d-argocd
server: https://my-vcluster-api.lo.mixinet.net:8443
secret:
name: my-vcluster-kubeconfig
sync:
toHost:
ingresses:
enabled: true
serviceAccounts:
enabled: true
fromHost:
ingressClasses:
enabled: true
nodes:
enabled: true
clearImageStatus: true
secrets:
enabled: true
mappings:
byName:
# Sync all Secrets from the 'my-vcluster-default' namespace to the
# virtual 'default' namespace.
"my-vcluster-default/*": "default/*"
# We could add other namespace mappings if needed, i.e.:
# "my-vcluster-kube-system/*": "kube-system/*"