Versions Compared

Key

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

...

Table of Contents
maxLevel3

Docker Image

Parasoft has published official Docker images to Docker Hub for your convenience. 

Deploying License Server in Kubernetes with a Helm Chart

...

Deploying License Server in Kubernetes Manually

Prerequisites

Namespace for LSS

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 LSS

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.

...

Code Block
languagetext
serviceaccount/parasoft-account created
role.rbac.authorization.k8s.io/parasoft-read created
rolebinding.rbac.authorization.k8s.io/parasoft-read-bind created

Custom Keystore

If you want to set up a custom keystore, you will need to create a configuration map for the .keystore and server.xml files. The command below creates a configuration map called "keystore-cfgmap" with file mappings for the custom .keystore and server.xml files. In this example, each file mapping is given a key: "keystore" for the .keystore file and "server-config" for the server.xml file. While giving each file mapping a key is not necessary, it is useful when you don't want the key to be the file name. 

Code Block
languagetext
~$ kubectl create configmap keystore-cfgmap --from-file=keystore=/path/to/.keystore --from-file=server-config=/path/to/server.xml
configmap/keystore-cfgmap created

Create the License Server Environment

To create the License Server environment, you will first need a yaml file that defines a Secret (optional), a volume, a Pod or StatefulSet, and a Service (optional). The Secret is used to pull the License Server image from the repository. The Pod or StatefulSet creates a pod set up to run a License Server container configured with a volume to persist data and a liveness probe for the container health. The Service makes License Server accessible via external clients by allocating ports in the node and mapping them to ports in the pod. 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.

Note: kind: Deployment is not supported. Use either kind: Pod or kind: StatefulSet, which are supported.

...

License Server Setup

Warning

Yaml files with kind: Deployment are not supported. Use either kind: Pod or kind: StatefulSet, which are supported. Be aware that once License Server has been deployed using Pod or StatefulSet, switching the Kind will invalidate machine-locked licenses.

To set up License Server, create a yaml file that defines the following:

  • Secret (optional)
    • To pull the License Server image from the repository.
  • Volume
    • To persist data.
  • Pod or StatefulSet
    • Creates a pod set up to run a License Server container configured with a volume to persist data and a liveness probe for the container health.
  • Service (optional).
    • Makes License Server accessible via external clients by allocating ports in the node and mapping them to ports in the pod.

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

As you modify either of the parasoft-lss.yaml samples shown below or craft your own yaml, be aware that the following fields need to be consistent across upgrades and redeployments in order to assure a stable machine ID:

  • metadata: name
  • metadata: namespace
  • containers: name

In addition, the following environment variables are required:

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

Example yaml using 'kind: Pod'

Code Block
languageyml
titleparasoft-lss.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-server
      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:
        - containerPort: 8080
          name: "http-server"
        - containerPort: 8443
          name: "https-server"
      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
---
apiVersion: v1
kind: Service
metadata:
  name: lss
  namespace: parasoft-lss-namespace
spec:
  type: NodePort
  selector:
    app: LSS
  ports:
    - port: 8080
      name: PORT_NAME_1
      nodePort: XXXXX
    - port: 8443
      name: PORT_NAME_2
      nodePort: XXXXX
   
# SERVICE CONFIG NOTES:
# 'name' can be whatever you want
# 'nodePort' must be between 30000-32768
# 'spec.selector' must match 'metadata.labels' in pod config

Example yaml using 'kind: StatefulSet'

Code Block
languageyml
titleparasoft-lss.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
  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-server
        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:
        - containerPort: 8080
          name: "http-server"
        - containerPort: 8443
          name: "https-server"
        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
---
apiVersion: v1
kind: Service
metadata:
  name: lss
  namespace: parasoft-lss-namespace
spec:
  type: NodePort
  selector:
    app: LSS
  ports:
    - port: 8080
      name: PORT_NAME_1
      nodePort: XXXXX
    - port: 8443
      name: PORT_NAME_2
      nodePort: XXXXX
    
# SERVICE CONFIG NOTES:
# 'name' can be whatever you want
# 'nodePort' must be between 30000-32768
# 'spec.selector' must match 'metadata.labels' in pod config between 30000-32768
# 'spec.selector' must match 'metadata.labels' in pod config

Create the License Server Environment

Use the yaml file to create the LSS environment:

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

To access the UI on a web browser, use the node ports allocated in the service definition as the address (for example, NODE_HOST:NODE_PORT).

If you injected JVM arguments into the container and want to verify their status, run the following commandUse the yaml file to create the LSS environment:

Code Block
languagetext
kubectl createexec <POD_NAME> -f parasoft-lss.yaml

To access the UI on a web browser, use the node ports allocated in the service definition as the address (for example, NODE_HOST:NODE_PORT).

If you injected JVM arguments into the container and want to verify their status, run the following command:

Code Block
languagetext
kubectl exec <POD_NAME> -c <CONTAINER_NAME> -- printenv

Required Settings for a Stable Machine ID

As you modify either of the parasoft-lss.yaml samples shown above or craft your own yaml, be aware that the following fields need to be consistent across upgrades and redeployments in order to assure a stable machine ID:

  • metadata: name
  • metadata: namespace
  • containers: name

In addition, the following environment variables are required:

...

c <CONTAINER_NAME> -- printenv

Custom Keystore

If you want to set up a custom keystore, you will need to create a configuration map for the .keystore and server.xml files. The command below creates a configuration map called "keystore-cfgmap" with file mappings for the custom .keystore and server.xml files. In this example, each file mapping is given a key: "keystore" for the .keystore file and "server-config" for the server.xml file. While giving each file mapping a key is not necessary, it is useful when you don't want the key to be the file name. 

Code Block
languagetext
~$ kubectl create configmap keystore-cfgmap --from-file=keystore=/path/to/.keystore --from-file=server-config=/path/to/server.xml
configmap/keystore-cfgmap created

...

Custom Truststore

Using a custom truststore in Kubernetes environments is similar to using a custom keystore as described above. Adjust the directions for using a custom keystore as appropriate. Note that the truststore location is /usr/local/parasoft/license-server/app/jre/lib/security/cacerts.

Troubleshooting

Enabling Additional Logging

  1. Copy log4j.xml from the <INSTALL_DIR>/app/ directory to <INSTALL_DIR>/data/.
  2. Open the log4j.xml file in <INSTALL_DIR>/data/ and add the following logger in Loggers element:

    Code Block
    languagetext
    <Logger name="com.parasoft.xtest" level="ALL">
      <AppenderRef ref="CONSOLE" />
    </Logger>
  3. Find commented-out section for LSS_JAVA_OPTS in the yaml file, uncomment it, then add the following as the value for LSS_JAVA_OPTS:

    Code Block
    languageyml
    -Dparasoft.cloudvm.verbose=true -Dparasoft.logging.config.file=/usr/local/parasoft/license-server/data/log4j.xml
  4. Restart the application.
  5. Additional logging will go to catalina log file (stdout).  You can run this command to get the log file to local file system (replace "lss-pod1-nfs" with your pod name and "parasoft-lss-namespace" with the namespace you used):

    Code Block
    languagetext
    kubectl logs lss-pod1-nfs -n parasoft-lss-namespace > lss-debug.log

Troubleshooting

machineId is LINUX2-0

This issue can occur when there is an underlying permission issue. To resolve it, try the following options:is an underlying permission issue. To resolve it, try the following options:

  1. Search the ls.log file found in the <LS_DATA_DIR>/logs/ directory for a "fails to get UUID" message.
  2. Verify that you have created permissions required by License Server using using parasoft-permissions.yaml.
    • Note: if you are upgrading, make sure to use the parasoft-permissions.yaml for the version to which you are upgrading.
  3. Confirm that all Parasoft-required resources are using the same namespace.

machineId changes when pod restarts

  1. This issue can occur if you are using an unsupported Kubernetes object. Make sure you are not

...

  1. using kind: Deployment.

...

  1. Only kind: Pod and kind: StatefulSet are supported.
  2. Make sure you are following all the directions under Required Settings for a Stable Machine ID.
  3. Make sure that your environment is not setting automountServiceAccountToken to false.