feat(longhorn): add longhorn

This commit is contained in:
Masaki Yatsu
2025-08-14 16:11:30 +09:00
parent 2717fed6a0
commit 04385257f7
6 changed files with 174 additions and 0 deletions

View File

@@ -6,5 +6,6 @@ default:
mod env mod env
mod k8s mod k8s
mod longhorn
import? "custom.just" import? "custom.just"

2
longhorn/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
tls.crt
tls.key

View File

@@ -0,0 +1,5 @@
apiVersion: longhorn.io/v1beta2
kind: Setting
metadata:
name: deleting-confirmation-flag
value: "true"

View File

@@ -0,0 +1,32 @@
# ForwardAuth with static upstreams configuration
# https://oauth2-proxy.github.io/oauth2-proxy/configuration/integration/#forwardauth-with-static-upstreams-configuration
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: oauth-auth
spec:
forwardAuth:
address: "http://oauth2-proxy.{{ .Env.LONGHORN_NAMESPACE }}" # w/ redirect
# address: "http://oauth2-proxy.{{ .Env.LONGHORN_NAMESPACE }}/oauth2/auth" # w/o redirect
trustForwardHeader: true
authResponseHeaders:
- X-Auth-Request-Access-Token
- Authorization
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: longhorn
spec:
entryPoints:
- websecure
routes:
- match: "Host(`{{ .Env.LONGHORN_HOST }}`)"
kind: Rule
services:
- name: longhorn-frontend
port: 80
middlewares:
- name: oauth-auth

128
longhorn/justfile Normal file
View File

@@ -0,0 +1,128 @@
set fallback := true
export LONGHORN_NAMESPACE := env("LONGHORN_NAMESPACE", "longhorn")
export LONGHORN_VERSION := env("LONGHORN_VERSION", "1.9.1")
export LONGHORN_OIDC_CLIENT_ID := env("LONGHORN_OIDC_CLIENT_ID", "longhorn")
export KEYCLOAK_REALM := env("KEYCLOAK_REALM", "")
[private]
default:
@just --list --unsorted --list-submodules
# Add Helm repository
add-helm-repo:
helm repo add longhorn https://charts.longhorn.io
helm repo update
# Remove Helm repository
remove-helm-repo:
helm repo remove longhorn
# Create namespace
create-namespace:
#!/bin/bash
set -euo pipefail
if ! kubectl get namespace ${LONGHORN_NAMESPACE} &>/dev/null; then
kubectl create namespace ${LONGHORN_NAMESPACE}
else
echo "Namespace ${LONGHORN_NAMESPACE} already exists."
fi
# Delete namespace
delete-namespace:
#!/bin/bash
set -euo pipefail
if kubectl get namespace ${LONGHORN_NAMESPACE} &>/dev/null; then
kubectl delete namespace ${LONGHORN_NAMESPACE} --ignore-not-found
else
echo "Namespace ${LONGHORN_NAMESPACE} does not exist."
fi
# Install Longhorn
install:
#!/bin/bash
set -euo pipefail
# https://longhorn.io/docs/1.9.1/deploy/install/install-with-helm/
just add-helm-repo
helm upgrade --cleanup-on-fail --install longhorn longhorn/longhorn \
--version ${LONGHORN_VERSION} -n ${LONGHORN_NAMESPACE} --create-namespace --wait \
-f longhorn-values.yaml
just set-replicas 1
# Uninstall Longhorn
uninstall:
#!/bin/bash
set -euxo pipefail
if ! kubectl get -n ${LONGHORN_NAMESPACE} settings.longhorn.io \
deleting-confirmation-flag &>/dev/null; then
kubectl apply -n ${LONGHORN_NAMESPACE} -f delete-setting.yaml
fi
helm uninstall longhorn -n ${LONGHORN_NAMESPACE} --ignore-not-found --wait
just delete-namespace
# Install oauth2-proxy for Longhorn
oauth2-proxy-install:
#!/bin/bash
set -euo pipefail
export KEYCLOAK_CLIENT_SECRET=$(just random-password)
just keycloak::delete-client ${KEYCLOAK_REALM} ${LONGHORN_OIDC_CLIENT_ID}
just keycloak::create-client ${KEYCLOAK_REALM} ${LONGHORN_OIDC_CLIENT_ID} \
"https://${LONGHORN_HOST}/oauth2/callback"
just keycloak::add-audience-mapper ${LONGHORN_OIDC_CLIENT_ID}
just create-namespace
KEYCLOAK_CLIENT_ID=${LONGHORN_OIDC_CLIENT_ID} \
KEYCLOAK_REALM=${KEYCLOAK_REALM} \
OAUTH2_PROXY_HOST=${LONGHORN_HOST} \
COOKIE_SECRET=$(just random-password) \
gomplate -f ../oauth2-proxy/configmap.gomplate.yaml | \
kubectl apply -n ${LONGHORN_NAMESPACE} -f -
kubectl apply -n ${LONGHORN_NAMESPACE} -f ../oauth2-proxy/deployment.yaml
kubectl apply -n ${LONGHORN_NAMESPACE} -f ../oauth2-proxy/service.yaml
OAUTH2_PROXY_HOST=${LONGHORN_HOST} \
gomplate -f ../oauth2-proxy/ingressroute.gomplate.yaml | \
kubectl apply -n ${LONGHORN_NAMESPACE} -f -
# Uninstall oauth2-proxy for Longhorn
oauth2-proxy-uninstall:
just keycloak::delete-client ${KEYCLOAK_REALM} ${LONGHORN_OIDC_CLIENT_ID}
OAUTH2_PROXY_HOST=${LONGHORN_HOST} \
gomplate -f ../oauth2-proxy/ingressroute.gomplate.yaml | \
kubectl delete -n ${LONGHORN_NAMESPACE} --ignore-not-found -f -
kubectl delete -n ${LONGHORN_NAMESPACE} --ignore-not-found service oauth2-proxy
kubectl delete -n ${LONGHORN_NAMESPACE} --ignore-not-found deployment oauth2-proxy
kubectl delete -n ${LONGHORN_NAMESPACE} --ignore-not-found configmap oauth2-proxy-config
# Set Longhorn number of replicas
set-replicas num='1':
#!/bin/bash
set -euo pipefail
if ! command -v jq &>/dev/null; then
echo "jq is not installed. Install jq." >&2
exit 1
fi
yaml=$(kubectl get -n ${LONGHORN_NAMESPACE} configmap longhorn-storageclass \
-o jsonpath='{.data.storageclass\.yaml}')
modified_yaml=$(echo "${yaml}" | sed 's/numberOfReplicas: "3"/numberOfReplicas: "{{ num }}"/')
kubectl patch -n ${LONGHORN_NAMESPACE} configmap longhorn-storageclass \
--type merge -p "$(cat <<EOF
{
"data": {
"storageclass.yaml": $(echo "${modified_yaml}" | jq -Rsa)
}
}
EOF
)"
# Create Longhorn IngressRoute
create-ingress:
just oauth2-proxy-install
LONGHORN_NAMESPACE=${LONGHORN_NAMESPACE} \
gomplate -f ingressroute.gomplate.yaml | \
kubectl apply -n ${LONGHORN_NAMESPACE} -f -
# Delete Longhorn IngressRoute
delete-ingress:
LONGHORN_NAMESPACE=${LONGHORN_NAMESPACE} \
gomplate -f ingressroute.gomplate.yaml | \
kubectl delete -n ${LONGHORN_NAMESPACE} --ignore-not-found -f -
just oauth2-proxy-uninstall

View File

@@ -0,0 +1,6 @@
ingress:
enabled: false
defaultSettings:
deletingConfirmationFlag: true
defaultReplicaCount: 1