mirror of
https://github.com/suitenumerique/docs.git
synced 2026-04-25 17:15:01 +02:00
save work with traefik
This commit is contained in:
@@ -1,2 +1,203 @@
|
||||
#!/bin/sh
|
||||
curl https://raw.githubusercontent.com/numerique-gouv/tools/refs/heads/main/kind/create_cluster.sh | bash -s -- impress
|
||||
set -o errexit
|
||||
|
||||
CURRENT_DIR=$(pwd)
|
||||
APPLICATION=${1:-app}
|
||||
CLUSTERNAME=${2:-suite}
|
||||
|
||||
echo "0. Create ca"
|
||||
# 0. Create ca
|
||||
mkcert -install
|
||||
cd /tmp
|
||||
mkcert "127.0.0.1.nip.io" "*.127.0.0.1.nip.io"
|
||||
cd $CURRENT_DIR
|
||||
|
||||
echo "1. Create registry container unless it already exists"
|
||||
# 1. Create registry container unless it already exists
|
||||
reg_name='kind-registry'
|
||||
reg_port='5001'
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
|
||||
docker run \
|
||||
-d --restart=always -p "127.0.0.1:${reg_port}:5000" --network bridge --name "${reg_name}" \
|
||||
registry:2
|
||||
fi
|
||||
|
||||
echo "2. Create kind cluster with containerd registry config dir enabled"
|
||||
# 2. Create kind cluster with containerd registry config dir enabled
|
||||
# TODO: kind will eventually enable this by default and this patch will
|
||||
# be unnecessary.
|
||||
#
|
||||
# See:
|
||||
# https://github.com/kubernetes-sigs/kind/issues/2875
|
||||
# https://github.com/containerd/containerd/blob/main/docs/cri/config.md#registry-configuration
|
||||
# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
|
||||
if ! kind get clusters | grep ${CLUSTERNAME}; then
|
||||
cat <<EOF | kind create cluster --name ${CLUSTERNAME} --config=-
|
||||
kind: Cluster
|
||||
apiVersion: kind.x-k8s.io/v1alpha4
|
||||
containerdConfigPatches:
|
||||
- |-
|
||||
[plugins."io.containerd.grpc.v1.cri".registry]
|
||||
config_path = "/etc/containerd/certs.d"
|
||||
nodes:
|
||||
- role: control-plane
|
||||
kubeadmConfigPatches:
|
||||
- |
|
||||
kind: InitConfiguration
|
||||
nodeRegistration:
|
||||
kubeletExtraArgs:
|
||||
node-labels: "ingress-ready=true"
|
||||
extraPortMappings:
|
||||
- containerPort: 30000
|
||||
hostPort: 80
|
||||
protocol: TCP
|
||||
- containerPort: 30001
|
||||
hostPort: 443
|
||||
protocol: TCP
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo "3. Add the registry config to the nodes"
|
||||
# 3. Add the registry config to the nodes
|
||||
#
|
||||
# This is necessary because localhost resolves to loopback addresses that are
|
||||
# network-namespace local.
|
||||
# In other words: localhost in the container is not localhost on the host.
|
||||
#
|
||||
# We want a consistent name that works from both ends, so we tell containerd to
|
||||
# alias localhost:${reg_port} to the registry container when pulling images
|
||||
REGISTRY_DIR="/etc/containerd/certs.d/localhost:${reg_port}"
|
||||
for node in $(kind get nodes --name ${CLUSTERNAME}); do
|
||||
docker exec "${node}" mkdir -p "${REGISTRY_DIR}"
|
||||
cat <<EOF | docker exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml"
|
||||
[host."http://${reg_name}:5000"]
|
||||
EOF
|
||||
done
|
||||
|
||||
echo "4. Connect the registry to the cluster network if not already connected"
|
||||
# 4. Connect the registry to the cluster network if not already connected
|
||||
# This allows kind to bootstrap the network but ensures they're on the same network
|
||||
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
|
||||
docker network connect "kind" "${reg_name}"
|
||||
fi
|
||||
|
||||
echo "5. Document the local registry"
|
||||
# 5. Document the local registry
|
||||
# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
|
||||
cat <<EOF | kubectl apply -f -
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: local-registry-hosting
|
||||
namespace: kube-public
|
||||
data:
|
||||
localRegistryHosting.v1: |
|
||||
host: "localhost:${reg_port}"
|
||||
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
|
||||
EOF
|
||||
|
||||
cat <<EOF | kubectl apply -f -
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: coredns
|
||||
namespace: kube-system
|
||||
data:
|
||||
Corefile: |
|
||||
.:53 {
|
||||
errors
|
||||
health {
|
||||
lameduck 5s
|
||||
}
|
||||
ready
|
||||
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
||||
pods insecure
|
||||
fallthrough in-addr.arpa ip6.arpa
|
||||
ttl 30
|
||||
}
|
||||
prometheus :9153
|
||||
forward . /etc/resolv.conf {
|
||||
max_concurrent 1000
|
||||
}
|
||||
rewrite stop {
|
||||
name regex (.*).127.0.0.1.nip.io traefik.traefik.svc.cluster.local answer auto
|
||||
}
|
||||
cache 30
|
||||
loop
|
||||
reload
|
||||
loadbalance
|
||||
}
|
||||
EOF
|
||||
|
||||
kubectl -n kube-system scale deployment coredns --replicas=1
|
||||
kubectl -n kube-system rollout restart deployments/coredns
|
||||
|
||||
if ! kubectl get ns traefik; then
|
||||
echo "6. Install Traefik ingress"
|
||||
helm repo add traefik https://traefik.github.io/charts
|
||||
helm repo update
|
||||
kubectl create namespace traefik
|
||||
|
||||
kubectl -n traefik create secret tls local-selfsigned-tls --key /tmp/127.0.0.1.nip.io+1-key.pem --cert /tmp/127.0.0.1.nip.io+1.pem || echo ok
|
||||
|
||||
|
||||
# Install the chart into the 'traefik' namespace
|
||||
helm install traefik traefik/traefik \
|
||||
--namespace traefik \
|
||||
--values ./traefik-values.yaml
|
||||
fi
|
||||
|
||||
if ! kubectl get ns ${APPLICATION}; then
|
||||
echo "7. Setup namespace"
|
||||
kubectl create ns ${APPLICATION}
|
||||
kubectl config set-context --current --namespace=${APPLICATION}
|
||||
kubectl -n ${APPLICATION} create secret generic mkcert --from-file=rootCA.pem="$(mkcert -CAROOT)/rootCA.pem" || echo ok
|
||||
kubectl -n impress create secret tls impress-docs-tls --key /tmp/127.0.0.1.nip.io+1-key.pem --cert /tmp/127.0.0.1.nip.io+1.pem || echo ok
|
||||
fi
|
||||
|
||||
if ! kubectl get configmap certifi -n ${APPLICATION}; then
|
||||
echo "8. Inject our custom CA in a configmap for certifi"
|
||||
curl https://raw.githubusercontent.com/certifi/python-certifi/refs/heads/master/certifi/cacert.pem -o /tmp/cacert.pem
|
||||
cat "$(mkcert -CAROOT)/rootCA.pem" >>/tmp/cacert.pem
|
||||
kubectl -n ${APPLICATION} create configmap certifi --from-file=cacert.pem=/tmp/cacert.pem
|
||||
kubectl -n ${APPLICATION} create secret generic certifi --from-file=/tmp/cacert.pem
|
||||
fi
|
||||
|
||||
echo "9. Check pod readiness across all namespaces..."
|
||||
|
||||
sleep_interval=10
|
||||
|
||||
echo "Initial wait time: $((sleep_interval * 2)) seconds…"
|
||||
sleep $((sleep_interval * 2))
|
||||
|
||||
check_pods_ready() {
|
||||
local max_attempts=60 # Maximum number of attempts (10 minutes with 10s intervals)
|
||||
local attempt=1
|
||||
|
||||
while [ $attempt -le $max_attempts ]; do
|
||||
echo "Attempt $attempt/$max_attempts - Checking pod status..."
|
||||
|
||||
not_ready_count=$( kubectl get po -A --no-headers | grep -v -E "Running|Completed"| wc -l | tr -d ' ')
|
||||
|
||||
if [ "$not_ready_count" -eq 0 ]; then
|
||||
echo "✅ All pods are ready!"
|
||||
return 0
|
||||
else
|
||||
echo "⏳ $not_ready_count pod(s) still not ready. Waiting $sleep_interval seconds…"
|
||||
sleep $sleep_interval
|
||||
((attempt++))
|
||||
fi
|
||||
done
|
||||
|
||||
echo "❌ Timeout: Some pods are still not ready after 10 minutes"
|
||||
echo "Final pod status:"
|
||||
kubectl get po -A
|
||||
return 1
|
||||
}
|
||||
|
||||
if check_pods_ready; then
|
||||
echo "🎉 Cluster is fully ready!"
|
||||
else
|
||||
echo "⚠️ Some pods may need manual intervention"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
96
bin/traefik-values.yaml
Normal file
96
bin/traefik-values.yaml
Normal file
@@ -0,0 +1,96 @@
|
||||
# Configure Network Ports and EntryPoints
|
||||
# EntryPoints are the network listeners for incoming traffic.
|
||||
ports:
|
||||
# Defines the HTTP entry point named 'web'
|
||||
web:
|
||||
port: 80
|
||||
nodePort: 30000
|
||||
# Instructs this entry point to redirect all traffic to the 'websecure' entry point
|
||||
http:
|
||||
redirections:
|
||||
entryPoint:
|
||||
to: websecure
|
||||
scheme: https
|
||||
permanent: true
|
||||
|
||||
# Defines the HTTPS entry point named 'websecure'
|
||||
websecure:
|
||||
port: 443
|
||||
nodePort: 30001
|
||||
|
||||
# Enables the dashboard in Secure Mode
|
||||
api:
|
||||
dashboard: true
|
||||
insecure: false
|
||||
|
||||
ingressRoute:
|
||||
dashboard:
|
||||
enabled: true
|
||||
matchRule: Host(`traefik.127.0.0.1.nip.io`)
|
||||
entryPoints:
|
||||
- websecure
|
||||
middlewares:
|
||||
- name: dashboard-auth
|
||||
|
||||
# Creates a BasicAuth Middleware and Secret for the Dashboard Security
|
||||
extraObjects:
|
||||
- apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: dashboard-auth-secret
|
||||
type: kubernetes.io/basic-auth
|
||||
stringData:
|
||||
username: admin
|
||||
password: "P@ssw0rd" # Replace with an Actual Password
|
||||
- apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: dashboard-auth
|
||||
spec:
|
||||
basicAuth:
|
||||
secret: dashboard-auth-secret
|
||||
|
||||
# We will route with Gateway API instead.
|
||||
ingressClass:
|
||||
enabled: true
|
||||
|
||||
# Enable Gateway API Provider & Disables the KubernetesIngress provider
|
||||
# Providers tell Traefik where to find routing configuration.
|
||||
providers:
|
||||
kubernetesIngress:
|
||||
enabled: true
|
||||
kubernetesGateway:
|
||||
enabled: false
|
||||
|
||||
## Gateway Listeners
|
||||
gateway:
|
||||
listeners:
|
||||
web: # HTTP listener that matches entryPoint `web`
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
namespacePolicy:
|
||||
from: All
|
||||
|
||||
websecure: # HTTPS listener that matches entryPoint `websecure`
|
||||
port: 443
|
||||
protocol: HTTPS # TLS terminates inside Traefik
|
||||
namespacePolicy:
|
||||
from: All
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- kind: Secret
|
||||
name: local-selfsigned-tls # the Secret we created before the installation
|
||||
group: ""
|
||||
|
||||
# Enable Observability
|
||||
logs:
|
||||
general:
|
||||
level: INFO
|
||||
# This enables access logs, outputting them to Traefik's standard output by default. The [Access Logs Documentation](https://doc.traefik.io/traefik/observability/access-logs/) covers formatting, filtering, and output options.
|
||||
access:
|
||||
enabled: true
|
||||
|
||||
# Enables Prometheus for Metrics
|
||||
metrics:
|
||||
prometheus:
|
||||
enabled: true
|
||||
@@ -7,6 +7,7 @@ const buildId = crypto.randomBytes(256).toString('hex').slice(0, 8);
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: 'export',
|
||||
allowedDevOrigins: ['docs.127.0.0.1.nip.io'],
|
||||
trailingSlash: true,
|
||||
images: {
|
||||
unoptimized: true,
|
||||
|
||||
@@ -22,13 +22,13 @@ minio:
|
||||
hostname: docs-minio.127.0.0.1.nip.io
|
||||
tls:
|
||||
enabled: true
|
||||
secretName: docs-tls
|
||||
secretName: impress-docs-tls
|
||||
consoleIngress:
|
||||
enabled: true
|
||||
hostname: docs-minio-console.127.0.0.1.nip.io
|
||||
tls:
|
||||
enabled: true
|
||||
secretName: docs-tls
|
||||
secretName: impress-docs-tls
|
||||
username: dinum
|
||||
password: password
|
||||
bucket: docs-media-storage
|
||||
@@ -44,16 +44,15 @@ keycloak:
|
||||
password: pass
|
||||
tls:
|
||||
enabled: true
|
||||
secretName: docs-tls
|
||||
secretName: impress-docs-tls
|
||||
db:
|
||||
username: dinum
|
||||
password: pass
|
||||
database: keycloak
|
||||
size: 1Gi
|
||||
image: postgres:16-alpine
|
||||
realm:
|
||||
realm:
|
||||
name: docs
|
||||
username: docs
|
||||
password: docs
|
||||
email: docs@example.com
|
||||
|
||||
|
||||
@@ -121,10 +121,6 @@ backend:
|
||||
python manage.py createsuperuser --email admin@example.com --password admin
|
||||
restartPolicy: Never
|
||||
|
||||
themeCustomization:
|
||||
enabled: true
|
||||
file_content: {{ readFile "./configuration/theme/demo.json" }}
|
||||
|
||||
# Extra volume mounts to manage our local custom CA and avoid to set ssl_verify: false
|
||||
extraVolumeMounts:
|
||||
- name: certs
|
||||
|
||||
@@ -10,5 +10,14 @@ metadata:
|
||||
annotations:
|
||||
{{- toYaml $.Values.serviceMedia.annotations | nindent 4 }}
|
||||
spec:
|
||||
type: ExternalName
|
||||
externalName: {{ $.Values.serviceMedia.host }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 9000
|
||||
protocol: TCP
|
||||
targetPort: 9000
|
||||
selector:
|
||||
app.kubernetes.io/component: frontend
|
||||
app.kubernetes.io/instance: impress
|
||||
app.kubernetes.io/name: docs
|
||||
sessionAffinity: None
|
||||
type: ClusterIP
|
||||
|
||||
Reference in New Issue
Block a user