Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Published by Scroll Versions from space LSDEV and version 2025.2

...

Deploying License Server in Kubernetes Manually

Prerequisites

Namespace for

...

License Server

First, create a namespace for License Server to run in. For example:

...

Warning

Once License Server has been licensed, deleting the namespace will invalidate machine-locked licenses, even if you recreate the same namespace.

Service Account for

...

License Server

Next, you will need a Kubernetes cluster. After starting the cluster, create the service account and permissions required by the License Server pod and related resources.

...

Example yaml files for a Pod or StatefulSet (both called "parasoft-lss.yaml") are shown below. These examples use an NFS volume, but that is not required; use the volume type that fits your needs best.

Required Settings for a Stable Machine ID
Anchor
RequiredSettingsForStableMachineID
RequiredSettingsForStableMachineID

...

  • env: name: PARASOFT_POD_NAME
  • env: name: PARASOFT_POD_NAMESPACE

Example yaml using 'kind: Pod'

Info

If you are using a secret for OIDC configuration, also see the Working with OIDC Secret section below.

Code Block
languageyml
titlelss-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: lss
  namespace: parasoft-lss-namespace
  labels:
    app: LSS
spec:
  volumes:
    - name: lss-data
      nfs:
        server: NFS_SERVER_HOST
        path: /lss/
# Uncomment section below if you are setting up a custom keystore; you will also need to uncomment out the associated volumeMounts below
#    - name: keystore-cfgmap-volume
#      configMap:
#        name: keystore-cfgmap
  securityContext:
    runAsNonRoot: true
  containers:
    - name: lss
      securityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop: ["ALL"]
        seccompProfile:
          type: RuntimeDefault    
      image: LSS_DOCKER_IMAGE
      imagePullPolicy: Always
      env:
        - name: PARASOFT_POD_NAME			    #REQUIRED, DO NOT CHANGE
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: PARASOFT_POD_NAMESPACE		    #REQUIRED, DO NOT CHANGE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
# To inject JVM arguments into the container, specify the "env" property as in the example below, which injects LSS_JAVA_OPTS
#        - name: LSS_JAVA_OPTS
#          value: "-Dparasoft.use.license.v2=true"
      ports:
         - name: "lss-http-port"
           containerPort: 8080
         - name: "lss-https-port"
           containerPort: 8443 
      volumeMounts:
        - mountPath: "/usr/local/parasoft/license-server/data"
          name: lss-data
# Uncomment section below if you are setting up a custom keystore. Note that updates made to these files will not be reflected inside the container once it's been deployed; you will need to restart the container for it to contain any updates.
#        - name: keystore-cfgmap-volume
#          mountPath: "/usr/local/parasoft/license-server/app/tomcat/conf/.keystore"
#          subPath: keystore
#        - name: keystore-cfgmap-volume
#          mountPath: "/usr/local/parasoft/license-server/app/tomcat/conf/server.xml"
#          subPath: server-config
# To prevent liveness probe failures on environments with low or overly taxed RAM/CPU, we recommend increasing the timeout seconds
      livenessProbe:
        exec:
          command:
          - healthcheck.sh
        initialDelaySeconds: 120
        periodSeconds: 60
        timeoutSeconds: 30
        failureThreshold: 5
  restartPolicy: Always
  serviceAccountName: parasoft-account
  automountServiceAccountToken: true
  imagePullSecrets:
    - name: YOUR_SECRET

Example yaml using 'kind: StatefulSet'

Info

If you are using a secret for OIDC configuration, also see the Working with OIDC Secret section below.

Code Block
languageyml
titlelss-pod.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: lss
  namespace: parasoft-lss-namespace
  labels:
    app: LSS
spec:
  selector:
    matchLabels:
      app: LSS
  serviceName: lss-service
  replicas: 1			#Only 1 is supported
  template:
    metadata:
      labels:
        app: LSS
    spec:
      volumes:
      - name: lss-data
        nfs:
          server: NFS_SERVER_HOST
          path: /lss/
#        persistentVolumeClaim:
#          claimName: lss-pvc
# Uncomment section below if you are setting up a custom keystore; you will also need to uncomment out the associated volumeMounts below
#      - name: keystore-cfgmap-volume
#        configMap:
#          name: keystore-cfgmap
      securityContext:
        runAsNonRoot: true
      containers:
      - name: lss
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: [ "ALL" ]
          seccompProfile:
            type: RuntimeDefault
        image: LSS_DOCKER_IMAGE
        imagePullPolicy: Always
        env:
        - name: PARASOFT_POD_NAME			    #REQUIRED, DO NOT CHANGE
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: PARASOFT_POD_NAMESPACE		    #REQUIRED, DO NOT CHANGE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
# To inject JVM arguments into the container, specify the "env" property as in the example below, which injects LSS_JAVA_OPTS
#        - name: LSS_JAVA_OPTS
#          value: "-Dparasoft.use.license.v2=true"
        ports:
           - name: "lss-http-port"
             containerPort: 8080
           - name: "lss-https-port"
             containerPort: 8443 
        volumeMounts:
        - name: lss-data
          mountPath: "/usr/local/parasoft/license-server/data"
# Uncomment section below if you are setting up a custom keystore. Note that updates made to these files will not be reflected inside the container once it's been deployed; you will need to restart the container for it to contain any updates.
#        - name: keystore-cfgmap-volume
#          mountPath: "/usr/local/parasoft/license-server/app/tomcat/conf/.keystore"
#          subPath: keystore
#        - name: keystore-cfgmap-volume
#          mountPath: "/usr/local/parasoft/license-server/app/tomcat/conf/server.xml"
#          subPath: server-config
# To prevent liveness probe failures on environments with low or overly taxed RAM/CPU, we recommend increasing the timeout seconds
        livenessProbe:
          exec:
            command:
            - healthcheck.sh
          initialDelaySeconds: 120
          periodSeconds: 60
          timeoutSeconds: 30
          failureThreshold: 5
      restartPolicy: Always
      serviceAccountName: parasoft-account
      automountServiceAccountToken: true
      imagePullSecrets:
        - name: YOUR_SECRET

Service Definition

Create the service that can be used to access the License Server in Kubernetes. The example shown below exposes it using a node port, which provides a stable endpoint for applications to access it.

...

Use the yaml file to create the LSS environmentLicense Server environment:

Code Block
languagetext
kubectl create -f parasoft-lss.yaml

...

Note: Do not mount /usr/local/parasoft/data-tmp.  You can ignore errors related to data-tmp like "rm: cannot remove '/usr/local/parasoft/data-tmp/LicenseServer/conf/licserv.enc': Read-only file system" in the Kubernetes logs.

Working with OIDC Secret (Optional)
Anchor
OIDCSecret
OIDCSecret

You can configure an OIDC secret for License Server. To do so:

  1. Create a secret for your OIDC configuration.
    Example OIDC secret yaml
    Code Block
    languageyml
    titlelss-oidc-secret.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: lss-oidc-secret
      namespace: parasoft-lss-namespace
    type: Opaque
    stringData:
      oidc_json: |
        {
            "enabled": true,
            "issuerUri": "your issuer uri",
            "clientId": "your client id",
            "clientSecret": "your client secret",
            "scopes": ["openid", "profile", "email"],
            "claimMappings": {
                "username": "preferred_username",
                "firstName": "given_name",
                "lastName": "family_name",
                "email": "email"
            },
            "adminUsers": ["your admin user"]
        }
  2. Update your lss-pod.yaml as follows:
    • Add an OIDC secret volume under spec.volumes:
      Code Block
      languageyml
      # Adding the OIDC secret as a volume
          - name: lss-oidc-secret-volume
            secret:
              secretName: lss-oidc-secret
              optional: true
              items:
              - key: oidc_json
                path: oidc.json
    • Add an initContainers section that will populate the data directory before the other containers are started under spec and before containers. This should use the License Server image and the License Server data directory /usr/local/parasoft/license-server/data:
      Code Block
      languageyml
      # Populating the data directory before main container starts
        initContainers:
          - name: init-lss-data
            image: LSS_DOCKER_IMAGE
            command: ["/bin/sh", "-c"]
            args:
              - |
                set -e
                if [ ! -f "$LSS_DATADIR/.lssrc" ]; then
                  touch "$LSS_DATADIR/.lssrc"
                  cp --preserve=timestamps -rnT "$TMP_DATADIR" "$LSS_DATADIR"
                fi
            volumeMounts:
              - mountPath: "/usr/local/parasoft/license-server/data"
                name: lss-data
    • Add an OIDC secret volume under spec.containers.name (=lss).volumeMounts:
      Code Block
      languageyml
      # Mounting the OIDC secret volume to the container
              - name: lss-oidc-secret-volume
                mountPath: "/usr/local/parasoft/license-server/data/conf/oidc.json"
                subPath: oidc.json
                readOnly: true

Troubleshooting

Enabling Additional Logging

...