Kubernetes support

Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.

It provides features such as:

  • Self-healing
  • Horizontal scaling
  • Service discover and load balancing
  • Secret and configuration management

Further information on Kubernetes can be found on the official Kubernetes Web site: https://kubernetes.io/.

Repository

The Security Access Manager image is available from the Docker Store repository: '/store/ibmcorp/isam'. To gain access to the image, you first need to request access to the image using your Docker Hub identity and the Docker Store Web site: https://store.docker.com. The Docker Store repository requires authentication before the image can be pulled into a local environment and as such it is treated as a private repository by Kubernetes. Instructions on how to configure Kubernetes to be able to access a private repository can be found in the official Kubernetes documentation:: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/.

At a high level a secret which contains the Docker Hub credential information should be created using the kubectl command. This secret can then be passed to the deployment descriptors using the 'imagePullSecrets' yaml entry. An example command is provided below (ensure that the kubectl context is set to the correct environment before running this command):

kubectl create secret docker-registry docker-login--docker-server=index.docker.io--docker-username=jdoe--docker-password=passw0rd--docker-email=jdoe@jks.com

Secrets

Sensitive information, like passwords should never be stored directly in the yaml deployment descriptors. They should instead be stored within a Kubernetes secret and then the secret should be referenced in the yaml deployment descriptors. Instructions on how to use Kubernetes secrets can be found in the official Kubernetes documentation: https://kubernetes.io/docs/concepts/configuration/secret/

In the examples provided within this chapter, a ‘secret’ is used to store the ISAM administration password. An example command to create the ‘secret’ is provided below (ensure that the kubectl context is set to the correct environment before running this command):
kubectl create secret generic isam-passwords --type=string --from-literal=cfgsvc=Passw0rd

Service Accounts

Service accounts can be used to provide an identity for processes that run in a Pod. Information on the usage of service accounts can be found in the official Kubernetes documentation: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/.

In the examples that are provided within this chapter, the deployment descriptors use the ‘isam’ service account. The kubectl utility can be used to create the ‘isam’ service account (ensure that the kubectl context is set to the correct environment before running this command):
kubectl create serviceaccount isam

Deployment

The following section illustrates how to deploy Security Access Manager containers into a Kubernetes environment.

Configuration Container

Instructions on how to create the Security Access Manager configuration container are provided in the following steps:

  1. Ensure that the kubectl context is set to the correct environment. The mechanism to do this differs based on the Kubernetes environment in use.
  2. Create a configuration file that is named config-container.yaml. This configuration file defines a configuration container that can be used to configure your environment.
    # 
    # The deployment description of the ISAM configuration container.  This
    # container is used to manage the configuration of the ISAM
    # environment.
    #
    
    apiVersion: apps/v1
    kind: Deployment
    
    metadata:
      name: isam-config
      labels:
        app: isam-config
    
    spec:
      selector:
        matchLabels:
          app: isam-config
    
      template: 
        metadata:
          labels:
            app: isam-config
    
        spec:
          # The name of the service account which has the required
          # capabilities enabled for the ISAM container.
          serviceAccountName: isam
    
          # We want to run the container as the isam (uid: 6000) user.
          securityContext:
            runAsNonRoot: true
            runAsUser:    6000
    
          # We use a volume to store the configuration snapshot for the 
          # environment.
          volumes:
            - name: isam-config
              emptyDir: {}
    
          containers:
            - name: isam-config
    
              # The fully qualified name of the ISAM image.
              image: store/ibmcorp/isam:9.0.7.0
    
              # The port on which the container will be listening.
              ports:
                - containerPort: 9443
    
              # Environment definition.  The administrator password is
              # contained within a Kubernetes secret.
              env:
                - name: SERVICE
                  value: config            
                - name: ADMIN_PWD
                  valueFrom:
                    secretKeyRef:
                      name: isam-passwords
                      key:  cfgsvc
    
              # The liveness and readiness probes are used by Kubernetes 
              # to obtain the health of the container.  Our health is 
              # governed by the ability to connect to the LMI.
              readinessProbe:
                tcpSocket:
                  port:  9443
                initialDelaySeconds: 5
                periodSeconds: 10
    
              livenessProbe:
                tcpSocket:
                  port: 9443
                initialDelaySeconds: 120
                periodSeconds: 20 
    
              # The '/var/shared' directory contains the configuration
              #  snapshots and should be persistent.  We use a volume for
              # this directory.
              volumeMounts:
                - mountPath: /var/shared
                  name: isam-config
    
          # The ISAM image lives in Docker Store and needs a docker
          # identity before the image can be accessed.
          imagePullSecrets:
            - name: docker-login
    
    ---
    
    # 
    # The service description of the ISAM configuration service.  The
    # service is only accessible from within the Kubernetes cluster.
    #
    
    apiVersion: v1
    kind: Service
    
    metadata:
      name: isam-config
    
    spec:
      ports:
        - port: 9443
          name: isam-config
    
      selector:
        app: isam-config
    
      type: ClusterIP
    
    
  3. Create the container:
    kubectl create –f config-container.yaml
  4. You can monitor the bootstrapping of the container using the 'logs' command:

    kubectl logs -f `kubectl get -o json pods -l app=isam-config | jq -r .items[0].metadata.name`

  5. Start the Kubernetes proxy so that you are able to access the Web management console of the configuration container. An alternative approach is to create a Kubernetes service that directly exposes the LMI port of the configuration container.

    kubectl port-forward `kubectl get -o json pods -l app=isam-config | jq -r .items[0].metadata.name` 9443

  6. Access the proxied Web administration console (https:/127.0.0.1:9443) authenticating as the 'admin' user, with a password of 'Passw0rd' (as defined in the isam-passwords secret). Proceed through the first-steps and then configure your environment.
  7. Using the Web administration console, publish the configuration of the environment.

Web Reverse Proxy Container

The following steps illustrate how to create a WebSEAL container for the 'default' WebSEAL instance:

  1. Ensure that the kubectl context is set to the correct environment. The mechanism to do this differs, based on the Kubernetes environment being used.
  2. Create a configuration file that is named wrp-container.yaml. This configuration file defines a WebSEAL container that can be used to secure access to your Web applications:
    # 
    # The deployment description of the ISAM Web Reverse Proxy container.  
    #
    
    apiVersion: apps/v1
    kind: Deployment
    
    metadata:
      name: isam-wrp
      labels:
        app: isam-wrp
    
    spec:
      selector:
        matchLabels:
          app: isam-wrp
    
      replicas: 1
    
      template: 
        metadata:
          labels:
            app: isam-wrp
    
        spec:
          # The name of the service account which has the required
          # capabilities enabled for the ISAM container.
          serviceAccountName: isam
    
          # We want to run the container as the isam (uid: 6000) user.
          securityContext:
            runAsNonRoot: true
            runAsUser:    6000
    
          containers:
            - name: isam-wrp
    
              # The fully qualified name of the ISAM image.
              image: store/ibmcorp/isam:9.0.7.0
    
              # The port on which the container will be listening.
              ports:
                - containerPort: 443
    
              # Environment definition for the 'default' Web reverse proxy 
              # instance.  The administrator password is contained
              # within a Kubernetes secret.
              env:
                - name: SERVICE
                  value: webseal
                - name: INSTANCE
                  value: default            
                - name: CONFIG_SERVICE_URL
                  value: https://isam-config:9443/shared_volume
                - name: CONFIG_SERVICE_USER_NAME
                  value: admin
                - name: CONFIG_SERVICE_USER_PWD
                  valueFrom:
                    secretKeyRef:
                      name: isam-passwords
                      key:  cfgsvc
    
              # The liveness and readiness probes are used by Kubernetes to
              # obtain the health of the container.  Our health is 
              # governed by the health_check.sh script which is provided 
              # by the container.
              livenessProbe:
                exec:
                  command:
                  - /sbin/health_check.sh 
                  - livenessProbe
                initialDelaySeconds: 10
                periodSeconds: 10
    
              readinessProbe:
                exec:
                  command:
                  - /sbin/health_check.sh
                initialDelaySeconds: 10
                periodSeconds: 10
    
          # The ISAM image lives in Docker Store and needs a docker
          # identity before the image can be accessed.
          imagePullSecrets:
            - name: docker-login
    
    
  3. Create the container:
    kubectl create –f wrp-container.yaml
  4. The 'isam_cli' command can be used to directly administer a WebSEAL container:

    kubectl exec -it `kubectl get -o json pods -l app=isam-wrp | jq -r .items[0].metadata.name` isam_cli

  5. You can monitor the bootstrapping of the container using the 'logs' command:

    kubectl logs -f `kubectl get -o json pods -l app=isam-wrp | jq -r .items[0].metadata.name`

  6. Create a configuration file that is named wrp-service.yaml. This configuration file defines a WebSEAL service that can be used to access WebSEAL. The type of service defined will be different based on whether the 'load balancer' service type is supported in the environment.

    The following definition can be used if the 'load balancer' service type is not supported in your environment:

    # 
    # The service description of the ISAM Web Reverse Proxy service.  This is
    # the entry point into the environment and can be accessed over port 
    # 30443 from outside of the Kubernetes cluster.
    #
    
    apiVersion: v1
    kind: Service
    
    metadata:
      name: isam-wrp
    
    spec:
      ports:
        - port: 443
          name: isam-wrp
          protocol: TCP
          nodePort: 30443
    
      selector:
        app: isam-wrp
    
      type: NodePort
    

    The following definition can be used it the 'load balancer' service type is supported in your environment:

    
    # LoadBalancer service definition....
    apiVersion: v1
    kind: Service
    metadata:
      name: isam-wrp
    spec:
      type: LoadBalancer
      ports:
        - port: 443
      selector:
        app: isam-wrp
    
    
  7. Create the service:
    kubectl create –f wrp-service.yaml
    1. If a 'LoadBalancer' service was defined, determine the external IP address of the service and then use your browser to access WebSEAL (port 443):
      kubectl get service isam-wrp --watch
    2. If a 'NodePort' service was defined, determine the IP address of the Kubernetes cluster and then use your browser to access WebSEAL (port 30443). In a 'minikube' environment the IP address of the cluster can be obtained with the following command:
      minikube ip

      In an IBM cloud environment, the IP address of the cluster can be obtained with the following command:

      bluemix cs workers mycluster --json | jq -r .[0].publicIP

Runtime Container

The ISAM Runtime Container (called isam-runtime, or ISAM Liberty Runtime) is similar to the Web Reverse Proxy Container. It is a personality of the ISAM image that runs the advanced authentication, context-based access and federation services. The isam-runtime container also retrieves a snapshot from the configuration container in the same manner as the Web Reverse Proxy Container. Besides the technical function of the container, the difference is that this container has no need to listen externally on a NodePort. Instead it only exposes its HTTPS interface on the cluster network with the isam-runtime service.

The following steps illustrate how to create a runtime container:

  1. Ensure that the kubectl context is set to the correct environment. The mechanism to do this differs, based on the Kubernetes environment that is being used.
  2. Create a configuration file that is named runtime-container.yaml. This configuration file defines a runtime container that can be used to secure access to your Web applications:
    # 
    # The deployment description of the ISAM runtime profile container. 
    # This container provides the Federation and Advanced Access Control
    # capabilities of ISAM.
    #
    
    apiVersion: apps/v1
    kind: Deployment
    
    metadata:
      name: isam-runtime
      labels:
        app: isam-runtime
    
    spec:
      selector:
        matchLabels:
          app: isam-runtime
    
      replicas: 1
    
      template: 
        metadata:
          labels:
            app: isam-runtime
    
        spec:
          # The name of the service account which has the required
          # capabilities enabled for the ISAM container.
          serviceAccountName: isam
    
          # We want to run the container as the isam (uid: 6000) user.
          securityContext:
            runAsNonRoot: true
            runAsUser:    6000
    
          containers:
            - name: isam-runtime
    
              # The fully qualified name of the ISAM image.
              image: store/ibmcorp/isam:9.0.7.0
    
              # The port on which the container will be listening.
              ports:
                - containerPort: 443
    
              # Environment definition.  The administrator password is
              # contained within a Kubernetes secret.
              env:
                - name: SERVICE
                  value: runtime
                - name: CONFIG_SERVICE_URL
                  value: https://isam-config:9443/shared_volume
                - name: CONFIG_SERVICE_USER_NAME
                  value: admin
                - name: CONFIG_SERVICE_USER_PWD
                  valueFrom:
                    secretKeyRef:
                      name: isam-passwords
                      key:  cfgsvc
    
              # The liveness and readiness probes are used by Kubernetes to
              # obtain the health of the container.  Our health is 
              # governed by the health_check.sh script which is provided 
              # by the container.
              livenessProbe:
                exec:
                  command:
                  - /sbin/health_check.sh 
                  - livenessProbe
                initialDelaySeconds: 10
                periodSeconds: 10
    
              readinessProbe:
                exec:
                  command:
                  - /sbin/health_check.sh
                initialDelaySeconds: 10
                periodSeconds: 10
    
          # The ISAM image lives in Docker Store and needs a docker
          # identity before the image can be accessed.
          imagePullSecrets:
            - name: docker-login
    
    ---
    
    # 
    # The service description of the ISAM runtime profile service.  The 
    # service is only accessible from within the Kubernetes cluster.
    #
    
    apiVersion: v1
    kind: Service
    
    metadata:
      name: isam-runtime
    
    spec:
      ports:
        - port: 443
          name: isam-runtime
      selector:
        app: isam-runtime
    
      type: ClusterIP
    
    
  3. Create the container:
    kubectl create –f runtime-container.yaml
  4. The 'isam_cli' command can be used to directly administer a runtime container:

    kubectl exec -it `kubectl get -o json pods -l app=isam-runtime | jq -r .items[0].metadata.name` isam_cli

  5. You can monitor the bootstrapping of the container using the 'logs' command:

    kubectl logs -f `kubectl get -o json pods -l app=isam-runtime | jq -r .items[0].metadata.name`

Distributed Session Cache

The ISAM Distributed Session Cache Container (called isam-dsc) is similar to the Web Reverse Proxy Container. It is a personality of the ISAM image that runs the distributed session cache and can be used by the Web Reverse Proxy and Runtime to share sessions between multiple containers. The isam-dsc container also retrieves a snapshot from the configuration container in the same manner as the Web Reverse Proxy Container. Besides the technical function of the container, the difference is that this container has no need to listen externally on a NodePort. Instead it only exposes its HTTPS and replication interface on the cluster network with the isam-dsc service.

The following steps illustrate how to create a DSC container:
  1. Ensure that the kubectl context is set to the correct environment. The mechanism to do this differs, based on the Kubernetes environment being used.
  2. Create a configuration file that is named dsc-container.yaml. This configuration file defines a DSC container that can be used to share sessions:
    # 
    # The deployment description of the ISAM distributed session cache
    # container.  
    #
    
    apiVersion: apps/v1
    kind: Deployment
    
    metadata:
      name: isam-dsc
      labels:
        app: isam-dsc
    
    spec:
      selector:
        matchLabels:
          app: isam-dsc
    
      template:
        metadata:
          labels:
            app: isam-dsc
    
        spec:
          # The name of the service account which has the required
          # capabilities enabled for the ISAM container.
          serviceAccountName: isam
    
          # We want to run the container as the isam (uid: 6000) user.
          securityContext:
            runAsNonRoot: true
            runAsUser:    6000
    
          containers:
            - name: isam-dsc
    
              # The fully qualified name of the ISAM image.
              image: store/ibmcorp/isam:9.0.7.0
    
              # The ports on which the container will be listening.  Port
              # 443 provides the main DSC service, and port 444 provides
              # the replication service which is used when replicating 
              # session data between DSC instances.
              ports:
                - containerPort: 443
                - containerPort: 444
    
              # Environment definition.  The administrator password is
              # contained within a Kubernetes secret.
              env:
                - name: SERVICE
                  value: dsc
                - name: INSTANCE
                  value: '1'
                - name: CONFIG_SERVICE_URL
                  value: https://isam-config:9443/shared_volume
                - name: CONFIG_SERVICE_USER_NAME
                  value: admin
                - name: CONFIG_SERVICE_USER_PWD
                  valueFrom:
                    secretKeyRef:
                      name: isam-passwords
                      key: cfgsvc
    
              # The liveness and readiness probes are used by Kubernetes to
              # obtain the health of the container.  Our health is 
              # governed by the health_check.sh script which is provided 
              # by the container.
              livenessProbe:
                exec:
                  command:
                  - /sbin/health_check.sh 
                  - livenessProbe
                initialDelaySeconds: 10
                periodSeconds: 10
    
              readinessProbe:
                exec:
                  command:
                  - /sbin/health_check.sh
                initialDelaySeconds: 10
                periodSeconds: 10
    
          # The ISAM image lives in Docker Store and needs a docker
          # identity before the image can be accessed.
          imagePullSecrets:
            - name: docker-login
    
    ---
    
    # 
    # The service description of the ISAM distributed session cache
    # service.  The service is only accessible from within the Kubernetes
    # cluster.
    #
    
    apiVersion: v1
    kind: Service
    
    metadata:
      name: isam-dsc
    
    spec:
      ports:
        - port: 443
          name: isam-dsc
        - port: 444
          name: isam-dsc-replica
      selector:
        app: isam-dsc
    
      type: ClusterIP
    
    
  3. Create the container:
    kubectl create –f dsc-container.yaml
  4. The 'isam_cli' command can be used to directly administer a DSC container:

    kubectl exec -it `kubectl get -o json pods -l app=isam-dsc | jq -r .items[0].metadata.name` isam_cli

  5. You can monitor the bootstrapping of the container using the 'logs' command:

    kubectl logs -f `kubectl get -o json pods -l app=isam-dsc | jq -r .items[0].metadata.name`

Kubernetes Environments

The following Kubernetes environments have been validated using the Security Access Manager image:

Minikube

Minikube is a tool that makes it easy to run Kubernetes locally. Minikube runs a single-node Kubernetes cluster inside a VM on your laptop for users looking to try out Kubernetes or develop with it day-to-day. Further information can be obtained from the Minikube Web site: https://kubernetes.io/docs/getting-started-guides/minikube/

To set the context for the kubectl utility use the following command:

kubectl config use-context minikube
IBM Cloud

The IBM cloud container service provides advanced capabilities for building cloud-native apps, adding DevOps to existing apps, and relieving the pain around security, scale, and infrastructure management. Further information can be obtained from the IBM Cloud Web site: https://www.ibm.com/cloud/container-service

To set the context for the kubectl utility use the IBM Cloud CLI to obtain the kubectl configuration file:

bx cs cluster-config <cluster-name>
Microsoft Azure Container Registry

Azure Container Service (AKS) manages your hosted Kubernetes environment, making it quick and easy to deploy and manage containerized applications without container orchestration expertise. It also eliminates the burden of ongoing operations and maintenance by provisioning, upgrading, and scaling resources on demand, without taking your applications offline. Further information can be obtained from the Microsoft Azure AKS Web Site: https://docs.microsoft.com/en-us/azure/aks/

To set the context for the kubectl utility use the Microsoft Azure CLI:

az aks get-credentials --resource-group <group-name> --name <cluster-name>
Google Cloud Platform

Google Cloud Platform lets you build and host applications and websites, store data, and analyze data on Google's scalable infrastructure. Further information can be obtained from the Google Cloud Web Site: https://cloud.google.com/kubernetes-engine/

To set the context for the kubectl utility use the Google Cloud CLI:

gcloud container clusters get-credentials <cluster-name>
Redhat Openshift
RedHat OpenShift is an open source container application platform based on the Kubernetes container orchestrator for enterprise application development and deployment. For more information, see: https://www.openshift.com/.
To set the context for the kubectl utility use the OpenShift CLI:
oc login

The oc binary is the preferred mechanism for accessing the OpenShift CLI and can be used interchangeably with the kubectl utility.

The default security context which is enabled by RedHat OpenShift is too restrictive for the ISAM container. As a result of this a less restrictive security context should be enabled for the service account which will run the ISAM containers (in the examples provided in this chapter we use the ‘isam’ service account).

The pre-defined ‘anyuid’ security context can be used, but this does provide additional capabilities that are not required by the ISAM containers. To create a security context with the minimum set of capabilities required for the ISAM containers:

  1. Ensure that the oc binary is available in the environment and that a login has already been performed.
  2. Create a configuration file that is named isam-scc.yaml. This configuration file defines a new security context which can be used by the ISAM containers:
    # 
    # The minimum security context constraints which are required to run
    # the ISAM container.  We cannot use the 'restricted' security
    # constraint as we need additional capabilities which would otherwise
    # be denied to the container.  The 'anyuid' security constraint may 
    # be used, but it allows additional capabilities which are not 
    # required by the container.
    #
    
    kind: SecurityContextConstraints
    apiVersion: v1
    
    # The name and description for the security context constraint to be
    # created.
    metadata:
      name: isam-scc
      annotations:
        kubernetes.io/description: The isam SCC allows the container to run
                     as any non-root user.
    
    # The following capabilities are not required.
    allowHostDirVolumePlugin: false
    allowHostIPC:             false
    allowHostNetwork:         false
    allowHostPID:             false
    allowHostPorts:           false
    allowPrivilegedContainer: false
    readOnlyRootFilesystem:   false
    
    # The priority is set to '10', otherwise the security constraint does
    # not take affect when applied to a service account.
    priority: 10
    
    # The ISAM container needs to be run as a 'custom' user, but does 
    # not need to run as the root user.
    runAsUser:
      type: MustRunAsNonRoot
    seLinuxContext:
      type: RunAsAny
    fsGroup:
      type: RunAsAny
    supplementalGroups:
      type: RunAsAny
    
    # The following volumes are required by the ISAM container.
    volumes:
    - configMap
    - emptyDir
    - projected
    - secret
    - downwardAPI
    - persistentVolumeClaim
    
    # By default we drop all capabilities and then only add back in the 
    # capabilities which are required by the ISAM container.
    requiredDropCapabilities:
    - ALL
    
    # The capabilities which are required by the ISAM container.
    allowedCapabilities:
    - CHOWN
    - DAC_OVERRIDE
    - FOWNER
    - KILL
    - NET_BIND_SERVICE
    - SETFCAP
    - SETGID
    - SETUID
    
    defaultAddCapabilities:
    - CHOWN
    - DAC_OVERRIDE
    - FOWNER
    - KILL
    - NET_BIND_SERVICE
    - SETFCAP
    - SETGID
    - SETUID
    
    
  3. Create the container:
    oc create -f -isam-scc.yaml
  4. Associate the new security context with the 'isam' user:
    oc adm policy add-scc-to-userisam-scc -z isam