Deploy StorageLink on AKS with Kubernetes Manifests
TLDR - Quick Summary
What: Deploy StorageLink on AKS using Kubernetes manifests managed with Kustomize
Steps: Create AKS cluster + Azure PostgreSQL, configure manifests, run
kubectl apply -k .Quick start:
kubectl apply -k k8s/
Overview
This guide walks through deploying StorageLink on Azure Kubernetes Service (AKS) using plain Kubernetes manifests, managed by Kustomize. This is an alternative to the Helm chart deployment — use this approach if your organization prefers raw manifests or does not use Helm.
This deployment uses an external Azure Database for PostgreSQL Flexible Server (no in-cluster database). The manifests include security hardening out of the box: NetworkPolicies, ServiceAccounts with token automount disabled, non-root containers, and IP-restricted load balancers.
For detailed configuration options (TLS modes, client IP preservation, security context, LFS mode, image verification, and more), see the Container Deployment Reference.
Architecture
┌──────────────────────────────────────────────┐
│ Azure Kubernetes Service (AKS) │
│ Namespace: storagelink │
│ │
HTTPS (443) │ ┌────────────┐ ┌────────────────┐ │
──────────────────┼──►│ Admin UI │───►│ Backend │ │
│ │ (Nginx) │ │ (Spring Boot) │ │
│ │ Port 8443 │ │ Port 8080 API │ │
│ └────────────┘ └───────┬────────┘ │
│ │ │
└─────────────────────────────┼────────────────┘
│
┌───────▼──────────┐
│ Azure Database │
│ for PostgreSQL │
│ Flexible Server │
└──────────────────┘
Components:
- Backend — StorageLink API server (Spring Boot). Handles cloud storage operations and user management.
- Admin UI — Web-based administration dashboard (Nginx). Exposed via a LoadBalancer on port 443.
- PostgreSQL — Azure-managed database storing user accounts and configuration data.
Prerequisites
- An Azure subscription
- Azure CLI installed and logged in
- kubectl installed (includes Kustomize since v1.14+)
- Access to StorageLink container images (provided per your engagement)
Deployment files
The deployment consists of Kubernetes manifest files managed by Kustomize:
| File | Description |
|---|---|
kustomization.yaml | Kustomize orchestration — sets namespace, labels, and resource order |
namespace.yaml | Creates the storagelink namespace |
serviceaccount.yaml | Dedicated ServiceAccounts with token automount disabled |
secrets.yaml | Template for database credentials, OAuth secrets, JWT key, license, and TLS certificate |
configmap.yaml | Non-sensitive configuration for the backend and UI |
networkpolicy.yaml | NetworkPolicies restricting pod-to-pod and egress traffic |
backend.yaml | Backend Deployment and ClusterIP Service |
ui.yaml | Admin UI Deployment and LoadBalancer Service (with IP restrictions) |
Step 1: Create an AKS cluster
# Create a resource group
az group create --name storagelink-rg --location centralus
# Create the AKS cluster
az aks create \
--resource-group storagelink-rg \
--name storagelink-aks \
--node-count 1 \
--node-vm-size Standard_DS2_v2 \
--generate-ssh-keys
# Get credentials for kubectl
az aks get-credentials --resource-group storagelink-rg --name storagelink-aks
Verify the cluster is ready:
kubectl get nodes
Step 2: Create the Azure PostgreSQL database
# Create a PostgreSQL Flexible Server
az postgres flexible-server create \
--name storagelink-pg \
--resource-group storagelink-rg \
--location centralus \
--admin-user swiftgw \
--admin-password '<your-strong-password>' \
--sku-name Standard_B1ms \
--tier Burstable \
--version 16 \
--storage-size 32 \
--database-name swift_gw \
--yes
# Allow the ltree extension (required by StorageLink)
az postgres flexible-server parameter set \
--server-name storagelink-pg \
--resource-group storagelink-rg \
--name azure.extensions \
--value LTREE
# Allow Azure services (including AKS) to connect
az postgres flexible-server firewall-rule create \
--name storagelink-pg \
--resource-group storagelink-rg \
--rule-name AllowAzureServices \
--start-ip-address 0.0.0.0 \
--end-ip-address 0.0.0.0
The ltree extension must be allowlisted before deploying StorageLink. Without it, the backend will fail to start because the database migration cannot create the extension.
Step 3: Set up image access
StorageLink container images are delivered per your engagement. Create a pull secret so Kubernetes can download them:
kubectl create namespace storagelink
kubectl create secret docker-registry storagelink-pull-secret \
--namespace storagelink \
--docker-server=<registry-url> \
--docker-username=<username> \
--docker-password=<password>
Step 4: Configure the manifests
4a. Update secrets
The secrets.yaml file is a template with REPLACE_ME placeholders. Fill in the values and apply it separately (it is excluded from Kustomize to prevent accidental commits of real credentials).
Generate secure values:
# Database password
openssl rand -base64 32
# OAuth client ID and secret (must match between backend and UI secrets)
openssl rand -hex 16
# JWT secret
openssl rand -base64 32
Generate a self-signed TLS certificate for testing:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes \
-subj "/CN=storagelink/O=YourOrg"
Update secrets.yaml with your values:
# storagelink-db-secret
stringData:
POSTGRES_USER: swiftgw
POSTGRES_PASSWORD: <generated-password> # Must match Azure PG password
POSTGRES_DB: swift_gw
# storagelink-backend-secret
stringData:
SPRING_DATASOURCE_USERNAME: swiftgw
SPRING_DATASOURCE_PASSWORD: <generated-password> # Must match above
SECURITY_CLIENT_ID: <generated-client-id> # Must match UI secret
SECURITY_CLIENT_SECRET: <generated-client-secret> # Must match UI secret
SECURITY_JWT_SECRET: <generated-jwt-secret>
LICENSE: <your-license-key> # Use "trial" for evaluation
# storagelink-ui-secret
stringData:
SECURITY_CLIENT_ID: <generated-client-id> # Must match backend
SECURITY_CLIENT_SECRET: <generated-client-secret> # Must match backend
WEBSITE_BUNDLE_CRT: |
-----BEGIN CERTIFICATE-----
<paste cert.pem contents>
-----END CERTIFICATE-----
WEBSITE_KEY: |
-----BEGIN PRIVATE KEY-----
<paste key.pem contents>
-----END PRIVATE KEY-----
For production, use Azure Key Vault with the Secrets Store CSI Driver to manage secrets outside of Kubernetes manifests.
4b. Update ConfigMap
Edit configmap.yaml and replace the PostgreSQL hostname placeholder:
# storagelink-backend-config
data:
DB_HOST: storagelink-pg.postgres.database.azure.com
SPRING_DATASOURCE_URL: jdbc:postgresql://storagelink-pg.postgres.database.azure.com:5432/swift_gw?sslmode=require
4c. Update container images
Edit backend.yaml and ui.yaml to set your container image references:
# backend.yaml
containers:
- name: backend
image: <your-registry>/storagelink-backend:<tag>
# ui.yaml
containers:
- name: ui
image: <your-registry>/storagelink-ui:<tag>
4d. Configure Admin UI access restrictions
The Admin UI should be restricted to authorized IP addresses. Edit ui.yaml and configure the Service with loadBalancerSourceRanges:
spec:
type: LoadBalancer
loadBalancerSourceRanges:
- "203.0.113.50/32" # Replace with your admin's IP
- "198.51.100.0/24" # Replace with your office network (optional)
The first person to reach the Admin UI can create the admin account. Always restrict access via loadBalancerSourceRanges before deploying.
Step 5: Deploy
Apply the secrets first (since they are excluded from Kustomize):
kubectl apply -f k8s/secrets.yaml
Then deploy all other resources:
kubectl apply -k k8s/
Monitor the deployment:
kubectl get pods -n storagelink -w
A healthy deployment looks like:
NAME READY STATUS RESTARTS AGE
backend-xxxxx 1/1 Running 0 2m
ui-xxxxx 1/1 Running 0 2m
ui-yyyyy 1/1 Running 0 2m
The backend may take 60–90 seconds to become ready due to database migrations on first launch.
Step 6: Access the Admin UI
Get the external IP of the UI service:
kubectl get svc ui -n storagelink
It may take 1–2 minutes for Azure to assign the external IP. Once available:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ui LoadBalancer 10.0.83.16 20.112.198.110 443:30121/TCP 2m
Open https://<EXTERNAL-IP> in your browser. You will see a certificate warning because the deployment uses a self-signed TLS certificate — this is expected for testing.
You will be prompted to create your admin account on first access via the setup wizard.
Initial admin account
On first access, StorageLink displays a setup wizard that lets you create the initial admin account. To prevent unauthorized access to the wizard, restrict the Admin UI to trusted IP addresses using loadBalancerSourceRanges on the UI Service.
Security features
The manifests include these security defaults:
- Non-root containers — backend runs as UID 100, UI runs as UID 1000
- Read-only root filesystem — enabled on the backend container
- Dropped capabilities — all Linux capabilities are dropped
- No privilege escalation —
allowPrivilegeEscalation: falseon all containers - NetworkPolicies — restrict pod-to-pod and egress traffic (DNS, PostgreSQL, HTTPS for cloud storage)
- ServiceAccounts — dedicated accounts with
automountServiceAccountToken: false - Pod anti-affinity — backend and UI replicas prefer spreading across nodes
- IP-restricted Admin UI —
loadBalancerSourceRangeson the LoadBalancer service - Backend not externally exposed — backend Service is
ClusterIP, preventingX-Forwarded-Forspoofing that would defeat login lockout and forge audit source IPs - Client IP preservation — UI Service uses
externalTrafficPolicy: Localto preserve the client's real source IP for audit logging and login lockout - Zero-downtime rolling updates — UI Deployment uses
maxSurge: 1, maxUnavailable: 0to avoid dropped connections under theLocaltraffic policy
Custom TLS certificate
Replace the self-signed certificate by updating WEBSITE_BUNDLE_CRT and WEBSITE_KEY in storagelink-ui-secret with your CA-signed certificate and key.
For production, consider using an Ingress controller with cert-manager for automated certificate management.
Configuration reference
Backend ConfigMap (storagelink-backend-config)
| Variable | Description | Example |
|---|---|---|
SPRING_PROFILES_ACTIVE | Spring profile | container,json-logs |
LOGGING_LEVEL_ROOT | Log level | INFO |
DB_HOST | PostgreSQL FQDN | storagelink-pg.postgres.database.azure.com |
SPRING_DATASOURCE_URL | Full JDBC URL | jdbc:postgresql://host:5432/swift_gw?sslmode=require |
FEATURES_INSTANCE_CLOUD_PROVIDER | Cloud provider hint | azure |
UI ConfigMap (storagelink-ui-config)
| Variable | Description | Example |
|---|---|---|
BACKEND_URL | Backend API endpoint (must include trailing slash) | http://backend:8080/ |
CLOUD_PROVIDER | Cloud provider hint | azure |
Resource summary
| Component | Memory (request/limit) | CPU (request/limit) | Storage |
|---|---|---|---|
| Backend (x2) | 2Gi / 3Gi | 500m / 1500m | — |
| Admin UI (x2) | 128Mi / 256Mi | 100m / 500m | — |
| Total | ~4.3Gi / ~6.5Gi | 1200m / 3500m | — |
The Azure Database for PostgreSQL Flexible Server resources are managed separately by Azure.
Troubleshooting
Backend pod CrashLoopBackOff
Check the backend logs:
kubectl logs -n storagelink -l app=backend --tail=50
Common causes:
ltreeextension not allowlisted — See the Azure Database setup in Step 2.- Database connection failed — Verify credentials match between
storagelink-db-secret,storagelink-backend-secret, and the Azure PostgreSQL server. Check firewall rules. - Insufficient memory — The backend requires at least 2Gi of memory.
Backend stuck on "Waiting for changelog lock"
This happens when a previous backend instance crashed during database migrations. The init container clears stale locks automatically on every pod start. If the issue persists:
# Scale backend to 0
kubectl scale deployment/backend -n storagelink --replicas=0
# Clear the lock manually
kubectl run -n storagelink pg-fix --rm -it --restart=Never \
--image=postgres:16-alpine --env="PGPASSWORD=<password>" \
-- psql -h <pg-server>.postgres.database.azure.com -U swiftgw -d swift_gw \
-c "UPDATE databasechangeloglock SET locked=false, lockgranted=null, lockedby=null WHERE id=1;"
# Scale backend back up
kubectl scale deployment/backend -n storagelink --replicas=1
UI pod CrashLoopBackOff
Check the UI logs:
kubectl logs -n storagelink -l app=ui --tail=50
Common causes:
- Invalid TLS certificate — Verify both
WEBSITE_BUNDLE_CRTandWEBSITE_KEYare valid PEM and match each other. Regenerate both together if needed. - Certificate/key mismatch — If you see
SSL_CTX_use_PrivateKey ... key values mismatch, the private key does not correspond to the certificate.
ImagePullBackOff
The image pull secret has expired or is misconfigured:
kubectl delete secret storagelink-pull-secret -n storagelink
kubectl create secret docker-registry storagelink-pull-secret \
--namespace storagelink \
--docker-server=<registry-url> \
--docker-username=<username> \
--docker-password="<token>"
kubectl delete pods -n storagelink --all
External IP stuck on \<pending>
kubectl describe svc ui -n storagelink
Check the Events section for error messages. Common causes include insufficient permissions on the AKS managed identity or Azure subscription quota limits.
Uninstalling
# Remove secrets
kubectl delete -f k8s/secrets.yaml
# Remove all other resources
kubectl delete -k k8s/
To also remove the Azure PostgreSQL server:
az postgres flexible-server delete --name storagelink-pg --resource-group storagelink-rg --yes
Manifest files
Create a k8s/ directory and add the following files. The step-by-step instructions above explain which values to customize.
k8s/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: storagelink
labels:
- pairs:
app.kubernetes.io/name: storagelink
app.kubernetes.io/version: "1.39.5"
resources:
- namespace.yaml
- serviceaccount.yaml
# secrets.yaml is a template — apply real secrets separately via kubectl
- configmap.yaml
- networkpolicy.yaml
- backend.yaml
- ui.yaml
k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: storagelink
labels:
pod-security.kubernetes.io/enforce: restricted
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: storagelink-quota
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
pods: "20"
---
apiVersion: v1
kind: LimitRange
metadata:
name: storagelink-limits
spec:
limits:
- default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
type: Container
k8s/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: storagelink-backend
automountServiceAccountToken: false
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: storagelink-ui
automountServiceAccountToken: false
k8s/secrets.yaml
# DO NOT commit this file with real values — it is in .gitignore.
# This is a template. Fill in values and apply with: kubectl apply -f secrets.yaml
#
# Generate secure values:
# Password: openssl rand -base64 32
# Client ID: openssl rand -hex 16
# Client Secret: openssl rand -hex 16
# JWT Secret: openssl rand -base64 32
#
# For production, use Azure Key Vault with the Secrets Store CSI Driver:
# https://learn.microsoft.com/en-us/azure/aks/csi-secrets-store-driver
apiVersion: v1
kind: Secret
metadata:
name: storagelink-db-secret
type: Opaque
stringData:
POSTGRES_USER: "REPLACE_ME"
POSTGRES_PASSWORD: "REPLACE_ME" # openssl rand -base64 32
POSTGRES_DB: "REPLACE_ME"
---
apiVersion: v1
kind: Secret
metadata:
name: storagelink-backend-secret
type: Opaque
stringData:
SPRING_DATASOURCE_USERNAME: "REPLACE_ME" # must match POSTGRES_USER
SPRING_DATASOURCE_PASSWORD: "REPLACE_ME" # must match POSTGRES_PASSWORD
SECURITY_CLIENT_ID: "REPLACE_ME" # openssl rand -hex 16 — must match UI secret
SECURITY_CLIENT_SECRET: "REPLACE_ME" # openssl rand -hex 16 — must match UI secret
SECURITY_JWT_SECRET: "REPLACE_ME" # openssl rand -base64 32
LICENSE: "REPLACE_ME"
---
apiVersion: v1
kind: Secret
metadata:
name: storagelink-ui-secret
type: Opaque
stringData:
SECURITY_CLIENT_ID: "REPLACE_ME" # must match backend secret
SECURITY_CLIENT_SECRET: "REPLACE_ME" # must match backend secret
WEBSITE_BUNDLE_CRT: "REPLACE_ME" # PEM-encoded certificate
WEBSITE_KEY: "REPLACE_ME" # PEM-encoded private key
k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: storagelink-backend-config
data:
SPRING_PROFILES_ACTIVE: container,json-logs
LOGGING_LEVEL_ROOT: INFO
DB_HOST: REPLACE_WITH_PG_FQDN
SPRING_DATASOURCE_URL: jdbc:postgresql://REPLACE_WITH_PG_FQDN:5432/swift_gw?sslmode=require
SERVER_PORT: "8080"
FEATURES_INSTANCE_CLOUD_PROVIDER: azure
FEATURES_SYSTEMD_NOTIFY: "false"
FEATURES_SFTP_SUBSYSTEM_AUTO_START: "false"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: storagelink-ui-config
data:
BACKEND_URL: "http://backend:8080/"
CLOUD_PROVIDER: azure
k8s/networkpolicy.yaml
# NetworkPolicies restrict pod-to-pod and egress traffic.
# Without these, any pod in the cluster can reach any other pod.
# Backend: only accept traffic from UI pods on port 8080
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-netpol
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: ui
ports:
- protocol: TCP
port: 8080
egress:
# Allow DNS resolution
- to: []
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
# Allow connection to Azure PostgreSQL (port 5432)
- to: []
ports:
- protocol: TCP
port: 5432
# Allow HTTPS egress for cloud storage connections (Azure Blob, AWS S3, GCS, etc.)
- to: []
ports:
- protocol: TCP
port: 443
---
# UI: accept traffic from the LoadBalancer on port 443, talk to backend on 8080
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ui-netpol
spec:
podSelector:
matchLabels:
app: ui
policyTypes:
- Ingress
- Egress
ingress:
- ports:
- protocol: TCP
port: 8443
egress:
# Allow DNS resolution
- to: []
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
# Allow connection to backend
- to:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 8080
k8s/backend.yaml
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
type: ClusterIP
selector:
app: backend
ports:
- name: http
port: 8080
targetPort: 8080
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: backend-pdb
spec:
maxUnavailable: 1
selector:
matchLabels:
app: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
serviceAccountName: storagelink-backend
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: backend
topologyKey: kubernetes.io/hostname
initContainers:
- name: wait-for-db
image: postgres:16-alpine
securityContext:
runAsUser: 70 # postgres user in alpine image
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: storagelink-backend-config
key: DB_HOST
envFrom:
- secretRef:
name: storagelink-db-secret
command:
- sh
- -c
- |
until pg_isready -h "$DB_HOST" -p 5432 -U "$POSTGRES_USER"; do
echo "Waiting for PostgreSQL..."
sleep 2
done
echo "PostgreSQL is ready"
echo "Clearing any stale Liquibase lock..."
PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$DB_HOST" -U "$POSTGRES_USER" -d "$POSTGRES_DB" \
-c "UPDATE databasechangeloglock SET locked=false, lockgranted=null, lockedby=null WHERE id=1;" 2>/dev/null || true
containers:
- name: backend
image: <your-registry>/storagelink-backend:<tag>
imagePullPolicy: Always
securityContext:
runAsUser: 100 # swiftgw user in the image
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
ports:
- containerPort: 8080
envFrom:
- secretRef:
name: storagelink-backend-secret
- configMapRef:
name: storagelink-backend-config
resources:
requests:
memory: "2Gi"
cpu: "500m"
limits:
memory: "3Gi"
cpu: "1500m"
volumeMounts:
- name: tmp
mountPath: /tmp
startupProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
failureThreshold: 30
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
periodSeconds: 10
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 180
periodSeconds: 20
volumes:
- name: tmp
emptyDir: {}
imagePullSecrets:
- name: storagelink-pull-secret
k8s/ui.yaml
apiVersion: v1
kind: Service
metadata:
name: ui
spec:
type: LoadBalancer
# Local preserves client IP; Cluster allows cross-node balancing but SNATs the source.
externalTrafficPolicy: Local
loadBalancerSourceRanges:
- "REPLACE_WITH_YOUR_CIDR" # e.g. "203.0.113.0/24" — restrict to your network
selector:
app: ui
ports:
- name: https
port: 443
targetPort: 8443
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: ui-pdb
spec:
maxUnavailable: 1
selector:
matchLabels:
app: ui
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: ui
template:
metadata:
labels:
app: ui
spec:
serviceAccountName: storagelink-ui
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: ui
topologyKey: kubernetes.io/hostname
containers:
- name: ui
image: <your-registry>/storagelink-ui:<tag>
imagePullPolicy: Always
securityContext:
runAsUser: 1000 # image default user that owns writable directories
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false # UI entrypoint writes to /etc/nginx/templates, /etc/nginx/conf.d, /var/run/swiftgw-webconfig
capabilities:
drop: ["ALL"]
ports:
- containerPort: 8443
envFrom:
- secretRef:
name: storagelink-ui-secret
- configMapRef:
name: storagelink-ui-config
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
volumeMounts:
- name: tmp
mountPath: /tmp
readinessProbe:
httpGet:
path: /
port: 8443
scheme: HTTPS
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: 8443
scheme: HTTPS
initialDelaySeconds: 10
periodSeconds: 20
volumes:
- name: tmp
emptyDir: {}
imagePullSecrets:
- name: storagelink-pull-secret
