cert-manager
This feature is only available for the following:
- Host Nodes
This feature is an Enterprise feature. See our pricing plans or contact our sales team for more information.
You can integrate cert-manager with your virtual cluster to manage TLS certificates across host and virtual environments.
Prerequisites​
- 
Administrator access to a Kubernetes cluster: See Accessing Clusters with kubectl for more information. Run the command kubectl auth can-i create clusterrole -Ato verify that your current kube-context has administrative privileges.infoTo obtain a kube-context with admin access, ensure you have the necessary credentials and permissions for your Kubernetes cluster. This typically involves using kubectl configcommands or authenticating through your cloud provider's CLI tools.
- 
helm: Helm v3.10 is required for deploying the platform. Refer to the Helm Installation Guide if you need to install it.
- 
kubectl: Kubernetes command-line tool for interacting with the cluster. See Install and Set Up kubectl for installation instructions.
- cert-manager operator installed on your host cluster. For setup instructions, see the cert-manager installation guide.
Enable the integration​
Enable cert-manager integration in your virtual cluster configuration:
integrations:
  certManager:
    enabled: true
This configuration enables the integration and configures automatic resource sync:
- Imports: Cluster-scoped ClusterIssuersfrom your host cluster into the virtual cluster
- Exports: Namespaced IssuersandCertificatesfrom the virtual cluster to the host cluster
- Syncs: Generated certificate secrets back to the virtual cluster automatically
Set up cluster contexts​
Create or update a virtual cluster following the vCluster quick start guide. Configure cluster contexts to simplify switching between host and virtual clusters:
export HOST_CTX="your-host-context"
export VCLUSTER_CTX="vcluster-ctx"
Run kubectl config get-contexts to list available contexts.
Certificate issuer configurations​
Choose the appropriate certificate issuer based on your security and operational requirements.
Self-signed certificates for development
Self-signed certificates work well for development environments and internal services that don't require public trust.
- Virtual Cluster Create a self-signed issuer self-signed-issuer.yaml- apiVersion: cert-manager.io/v1
 kind: Issuer
 metadata:
 name: selfsigned-issuer
 namespace: default
 spec:
 selfSigned: {}- Apply the issuer: Apply self-signed issuer- kubectl --context=$VCLUSTER_CTX apply -f self-signed-issuer.yaml
- Virtual Cluster Create a certificate self-signed-certificate.yaml- apiVersion: cert-manager.io/v1
 kind: Certificate
 metadata:
 name: app-tls-cert
 namespace: default
 spec:
 secretName: app-tls-secret
 duration: 2160h # 90 days
 renewBefore: 360h # 15 days
 commonName: myapp.local
 dnsNames:
 - myapp.local
 - api.myapp.local
 privateKey:
 algorithm: RSA
 size: 2048
 issuerRef:
 name: selfsigned-issuer
 kind: Issuer- Apply the certificate: Apply certificate- kubectl --context=$VCLUSTER_CTX apply -f self-signed-certificate.yaml
Self-signed certificates generate browser warnings and should not be used in production environments accessible to external users.
Private PKI for enterprise environments
Private PKI configurations provide enterprise-grade certificate management with custom certificate authorities.
- Host Cluster Create a root CA certificate - Create a self-signed root CA in the host cluster (ClusterIssuers are imported from host to virtual cluster): root-ca.yaml- apiVersion: cert-manager.io/v1
 kind: ClusterIssuer
 metadata:
 name: selfsigned-issuer
 spec:
 selfSigned: {}
 ---
 apiVersion: cert-manager.io/v1
 kind: Certificate
 metadata:
 name: root-ca-cert
 namespace: cert-manager
 spec:
 isCA: true
 commonName: "Enterprise Root CA"
 subject:
 organizations:
 - "Enterprise Corp"
 organizationalUnits:
 - "IT Security"
 countries:
 - "US"
 secretName: root-ca-secret
 duration: 87600h # 10 years
 renewBefore: 78840h # 9 years
 privateKey:
 algorithm: ECDSA
 size: 256
 issuerRef:
 name: selfsigned-issuer
 kind: ClusterIssuer- Apply in the host cluster: Apply root CA in host cluster- kubectl --context=$HOST_CTX apply -f root-ca.yaml
- Host Cluster Create a CA issuer ca-issuer.yaml- apiVersion: cert-manager.io/v1
 kind: ClusterIssuer
 metadata:
 name: enterprise-ca-issuer
 spec:
 ca:
 secretName: root-ca-secret- Apply in the host cluster: Apply CA issuer in host cluster- kubectl --context=$HOST_CTX apply -f ca-issuer.yaml
- Virtual Cluster Issue certificates from your CA ca-signed-certificate.yaml- apiVersion: cert-manager.io/v1
 kind: Certificate
 metadata:
 name: enterprise-app-cert
 namespace: default
 spec:
 secretName: enterprise-app-tls
 duration: 8760h # 1 year
 renewBefore: 720h # 30 days
 commonName: myapp.enterprise.local
 dnsNames:
 - myapp.enterprise.local
 - api.myapp.enterprise.local
 subject:
 organizations:
 - "Enterprise Corp"
 organizationalUnits:
 - "Application Services"
 usages:
 - digital signature
 - key encipherment
 - server auth
 issuerRef:
 name: enterprise-ca-issuer
 kind: ClusterIssuer- Apply in the virtual cluster: Apply certificate in virtual cluster- kubectl --context=$VCLUSTER_CTX apply -f ca-signed-certificate.yaml
Security considerations:
- Store root CA private keys securely and offline when possible
- Implement proper certificate lifecycle management
- Monitor certificate expiration dates
- Establish clear revocation procedures
ACME for public-facing services
ACME (Automatic Certificate Management Environment) issuers like Let's Encrypt provide free, automatically-renewed certificates for public-facing services.
- Virtual Cluster Create an ACME issuer acme-issuer.yaml- apiVersion: cert-manager.io/v1
 kind: Issuer
 metadata:
 name: letsencrypt-prod
 namespace: default
 spec:
 acme:
 email: admin@yourdomain.com
 server: https://acme-v02.api.letsencrypt.org/directory
 privateKeySecretRef:
 name: letsencrypt-prod-account-key
 solvers:
 - http01:
 ingress:
 ingressClassName: nginx
 - dns01:
 cloudflare:
 email: admin@yourdomain.com
 apiKeySecretRef:
 name: cloudflare-api-key-secret
 key: api-key
- Virtual Cluster Create an ACME certificate acme-certificate.yaml- apiVersion: cert-manager.io/v1
 kind: Certificate
 metadata:
 name: public-app-cert
 namespace: default
 spec:
 secretName: public-app-secret
 duration: 2160h # 90 days
 renewBefore: 720h # 30 days
 dnsNames:
 - myapp.example.com
 - api.myapp.example.com
 issuerRef:
 name: letsencrypt-prod
 kind: Issuer
Rate limits: Let's Encrypt enforces rate limits. Use staging environment (https://acme-staging-v02.api.letsencrypt.org/directory) for testing.
PKI for compliance requirements
PKI configurations require specific certificate formats and validation procedures for compliance with standards.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: gov-service-cert
  namespace: default
spec:
  secretName: gov-service-secret
  duration: 8760h # 1 year maximum
  renewBefore: 2160h # 90 days
  commonName: service.application.1234567890
  subject:
    organizations:
      - "Organization"
    organizationalUnits:
      - "PKI"
      - "CONTRACTOR"
    countries:
      - "US"
  usages:
  - digital signature
  - key encipherment
  - server auth
  privateKey:
    algorithm: RSA
    size: 2048  # Federal minimum requirement
  issuerRef:
    name: gov-pki-issuer
    kind: ClusterIssuer
Compliance requirements:
- Use hierarchical 3-tier CA structure
- Include specific Distinguished Name fields
- Maintain Certificate Revocation Lists (CRLs)
- Follow Federal PKI Certificate Policy guidelines
Verify certificate creation​
Check that your certificates generate correctly:
- Virtual Cluster Check certificate status Verify certificate creation- kubectl --context=$VCLUSTER_CTX describe certificate <certificate-name> -n <namespace>- Look for - Ready: Truein the status conditions.
- Virtual Cluster Verify secret creation Check certificate secret- kubectl --context=$VCLUSTER_CTX get secret <secret-name> -n <namespace> -o yaml- Confirm the secret contains - tls.crtand- tls.keydata.
- Host Cluster Confirm synchronization Check host cluster resources- kubectl --context=$HOST_CTX get certificate,issuer -A- Verify resources appear in the host cluster namespace. 
Use certificates in applications​
Reference your certificate secrets in Ingress resources:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: secure-app-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  tls:
    - hosts:
        - myapp.example.com
      secretName: your-tls-secret  # Use the secretName from your Certificate
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-service
                port:
                  number: 80
Replace your-tls-secret with the actual secretName specified in your Certificate resource (e.g., app-tls-secret, enterprise-app-tls, or public-app-secret from the examples above).
Troubleshooting​
Certificate creation issues
Check certificate status:
kubectl --context=$VCLUSTER_CTX describe certificate <name>
Common problems:
- Pending status: Check CertificateRequest events
- Failed validation: Verify DNS/HTTP challenge accessibility
- Rate limiting: Switch to staging ACME server for testing
Examine certificate requests:
kubectl --context=$VCLUSTER_CTX get certificaterequests
kubectl --context=$VCLUSTER_CTX describe certificaterequest <name>
Integration synchronization problems
Verify integration status:
Host Clusterkubectl --context=$HOST_CTX -n cert-manager get pods
kubectl --context=$HOST_CTX -n cert-manager logs deployment/cert-manager
# Check if integration is enabled
kubectl --context=$VCLUSTER_CTX get configmap vcluster-config -o yaml
# Check resource synchronization
kubectl --context=$VCLUSTER_CTX get events --field-selector reason=Sync
Common synchronization issues:
- RBAC permissions missing on host cluster
- Network policies blocking communication
- Resource naming conflicts between clusters
ACME challenge failures
For detailed troubleshooting of ACME challenges:
Check challenge status:
kubectl --context=$VCLUSTER_CTX describe order <order-name>
kubectl --context=$VCLUSTER_CTX describe challenge <challenge-name>
For comprehensive ACME troubleshooting, including HTTP-01 and DNS-01 challenge issues, see the cert-manager ACME troubleshooting guide.
For troubleshooting guidance, see the cert-manager troubleshooting documentation.
Advanced configuration​
Custom sync configurations
Fine-tune resource synchronization behavior:
integrations:
  certManager:
    enabled: true
    sync:
      toHost:
        certificates:
          enabled: true
        issuers:
          enabled: true
      fromHost:
        clusterIssuers:
          enabled: true
          selector:
            labels:
              vcluster.loft.sh/managed: "true"
Configuration options:
- selector: Filter which ClusterIssuers to import
- Individual resource type controls for granular sync management
Configuration reference​
certManager required object  ​
CertManager reuses a host cert-manager and makes its CRDs from it available inside the vCluster.
- Certificates and Issuers will be synced from the virtual cluster to the host cluster.
- ClusterIssuers will be synced from the host cluster to the virtual cluster.
certManager required object  ​enabled required boolean false ​
Enabled defines if this option should be enabled.
enabled required boolean false ​sync required object  ​
Sync contains advanced configuration for syncing cert-manager resources.
sync required object  ​toHost required object  ​
toHost required object  ​