Bookmark this page

Managing Application Deployments

Objectives

  • Configure and manage application deployments on Red Hat OpenShift.

Manage Deployments with CLI

The oc utility provides several command-line options to manage deployments. The following list describes some of the available options:

oc rollout

The oc rollout command provides the cancel, pause, undo, retry, and more options for your deployments and deployment configurations.

For example, consider that you updated the example-deployment image. The following command waits until the deployment rollout is successful:

[user@host ~]$ oc rollout status deployment example-deployment
Waiting for deployment "example-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "example-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "example-deployment" successfully rolled out

The following command undoes the deployment change:

[user@host ~]$ oc rollout undo deployment example-deployment
deployment.apps/example-deployment rolled back

The following command pauses the automatic rollout of deployment after you modify the resource:

[user@host ~]$ oc rollout pause deployment example-deployment
deployment.apps/example-deployment paused

After you make modifications to the resource, you can then resume the resource:

[user@host ~]$ oc rollout resume deployment example-deployment
deployment.apps/example-deployment resumed

Execute oc rollout -h for more information about each oc rollout command.

oc scale

The oc scale command scales the number of replicas for a given deployment or deployment configuration:

[user@host ~]$ oc scale deployment example-deployment --replicas=3
deployment.apps/example-deployment scaled

After you scale the deployment, the deployment maintains three identical pods:

[user@host ~]$ oc get pod
NAME                      READY   STATUS    RESTARTS   AGE
example-7b867784f-4f98j   1/1     Running   0          115s
example-7b867784f-jbjkq   1/1     Running   0          117s
example-7b867784f-lwh5h   1/1     Running   0          2m7s

Externalize Deployment Configuration

Applications often require runtime configuration that might differ with the environment in which the application is running. For example, an application might require the following configuration:

  • Database user and password

  • API endpoints

  • Proxy configuration, such as HTTPd or NGINX configuration file

  • TLS certificates

  • Feature toggles

For example, developers can promote an application from a development environment to a production environment by reusing the same container image and modifying the configuration data.

Using Secret and Configuration Map Resources

Depending on the sensitivity of the data, you can use the configuration map (ConfigMap) or secret (Secret) OpenShift objects to externalize the data.

Use secrets to store sensitive information, such as passwords, keys, and tokens. OpenShift provides a number of secret types:

  • service-account-token

  • basic-auth

  • ssh-auth

  • tls

  • opaque

You can use the secret types to validate the key and data in the secret. The opaque secret type does not provide any validation, and is considered a general puprpose secret type.

Secrets encode the data by using base64 encoding. When OpenShift injects secret data into a container, the data is decoded and either mounted as a file, or injected as environment variables inside the container.

Warning

OpenShift does not encrypt secrets by default. Consequently, developers are often discouraged from storing secrets in plain text in remote systems, such as git. To encrypt secrets, use external projects, like the Sealed Secrets project. See the references section for more information about sealed secrets.

Configuration maps store nonsensitive data. You can store individual properties as well as entire configuration files and JSON data in configuration maps.

Create Secrets and Configuration Maps

The the section called “Configuring OpenShift to Use the Registry Credentials” section describes creating secrets by using the oc command-line interface (CLI) and the OpenShift web console.

Similarly to secrets, you can create configuration maps by using the oc create command:

[user@host ~]$ oc create configmap example-cm \
--from-literal key1=value1 \
--from-literal key2=value2
configmap/example-cm created

The previous command creates the following YAML object:

kind: ConfigMap
metadata:
    name: example-cm
apiVersion: v1
data:
    key1: value1
    key2: value2

You can also create configuration maps from a file, or a directory:

[user@host ~]$ oc create configmap example-cm \
--from-file=redis.conf
configmap/example-cm created

The preceding example creates a configuration map with the redis.conf key and the contents of the file as its value. Developers might also rename the key, such as:

[user@host ~]$ oc create configmap example-cm \
--from-file=primary=/etc/redis/redis.conf \
--from-file=replica=replica-redis.conf
configmap/example-cm created

The preceding example creates a configuration map with the following keys:

  • The primary key with the contents of the local /etc/redis/redis.conf file.

  • The replica key with the contents of the local ./replica-redis.conf file.

Finally, similarly to secrets, you can use the OpenShift web console to create configuration maps. In the developer perspective, click ConfigMaps, select your project, and click Create ConfigMap.

Figure 5.1: Create configuration maps in the OpenShift console

Manage Secrets and Configuration Maps

The following commands are common to the secret and configuration maps. You can use either secret or configmap as the resource type.

View resources

To view details of a resource, use the oc get command:

[user@host ~]$ oc get secret mysecret -o yaml
...output omitted...

The -o yaml parameter displays the resource in the YAML language.

Edit resources

To edit a resource, use the oc edit command:

[user@host ~]$ oc edit configmap my-cm
...output omitted...

Alternatively, you can edit resources in the OpenShift web console.

Patch resources

Patching a resource means editing the resource non-interactively. This is useful, for example, in scripts. Use the oc patch command to patch a resource, for example:

[user@host ~]$ oc patch configmap/my-cm \
--patch '{"data":{"key1":"newvalue1"}}'
configmap/my-cm patched

The preceding command changes the .data.key1 key to the newvalue1 value.

The preceding commands work on any OpenShift resource. However, to edit secrets, you must use values in base64 encoding. You can encode any string by using the base64 command, for example:

[user@host ~]$ echo -n 'hunter3' | base64
aHVudGVyMw==

The preceding echo command uses the -n parameter to remove a new line from the text. You can use the encoded value to edit secrets.

Note

You can use the base64 command to decode any text as well:

[user@host ~]$ echo -n 'aHVudGVyMw==' | base64 --decode
hunter3

Finally, you can use the oc extract command to extract the contents of a configuration map or a secret to a directory:

[user@host ~]$ oc extract secret/my-secret --to=/tmp/secret
/tmp/secret/user
/tmp/secret/pass

This means that you can edit the file contents, and use the oc set data command to edit the secret:

[user@host ~]$ oc set data secret/my-secret --from-file=/tmp/secret
secret/my-secret data updated

Inject Data to Pods

You can mount configuration maps and secrets as data volumes, or expose the data as environment variables, inside an application container.

Note

Both configuration maps and secrets are namespaced resources. Consequently, your deployments cannot refer to secrets or configuration maps in a different project. The following section assumes that both the deployment and the secret or configuration map reside in the same project.

To inject all values stored in a configuration map or secret into environment variables for pods created from a deployment, use the oc set env command:

[user@host ~]$ oc set env deployment my-deployment \
--from configmap/my-cm
deployment.apps/my-deployment updated

The preceding command configures the spec.containers.env pod property. For each key in the configuration map, the command creates an uppercase key with the value that refers to the configuration map:

...deployment omitted...
      spec:
        containers:
        - command:
          - sleep
          - infinity
          env:
          - name: KEY1
            valueFrom:
              configMapKeyRef:
                key: key1
                name: my-cm
          image: registry.access.redhat.com/ubi8/ubi:8.0
          imagePullPolicy: IfNotPresent
...deployment omitted...

To mount all keys from a configuration map or secret as files, use the oc set volume command:

[user@host ~]$ oc set volume deployment my-deployment --add \
-t secret -m /path/to/mount/volume \
--name myvol --secret-name my-secret
deployment.apps/my-deployment volume updated

The preceding command defines a new volume in a deployment, and mounts it to the specified path:

...deployment omitted...
    spec:
      containers:
      - command:
        - sleep
        - infinity
        image: registry.access.redhat.com/ubi8/ubi:8.0
        imagePullPolicy: IfNotPresent
        name: ubi
        volumeMounts:
        - mountPath: /mnt/secret
          name: myvol
      volumes:
      - name: myvol
        secret:
          defaultMode: 420
          secretName: my-secret

OpenShift injects the contents ot the secret or configuration map resources during the pod creation.

Note

When you update a secret or configuration map, already running pods still refer to the original values. Only new pods receive the updated values.

Consequently, after you update a secret or configuration map, you must recreate already running pods.

Using Service Accounts

Service accounts provide identity for applications. This means that administrators can bind roles for role-based access control (RBAC), secrets, security context constraints (SCCs), and other objects to service accounts.

Developers then associate service accounts to pods. Applications can use service accounts to, for example, invoke OpenShift API. This is useful, for example, when applications such as operators create and manage custom OpenShift resources. Operators are out of scope for this course.

OpenShift associates each service account with a JSON Web Token (JWT) that is mounted inside of a pod that uses the service account. Every pod uses the default service account by default.

Create and Assign Service Accounts to Applications

You can create a service account by using the oc create command:

[user@host ~]$ oc create serviceaccount my-sa
serviceaccount/my-sa created

The previous command creates the following YAML object:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-sa
  namespace: my-ns
imagePullSecrets:
- name: my-sa-dockercfg-rxbhw
secrets:
- name: my-sa-dockercfg-rxbhw

You can assign a custom service account to a deployment or a pod by using the oc set serviceaccount command:

[user@host ~]$ oc set serviceaccount \
deployment nginx-deployment my-sa
deployment.apps/nginx-deployment serviceaccount updated

Use Service Account User

When you create a pod, OpenShift mounts the token, together with other data, in the /var/run/secrets/kubernetes.io/serviceaccount directory.

For example, consider a test pod in the example-ns namespace:

[user@host ~]$ oc exec test -- \
ls /var/run/secrets/kubernetes.io/serviceaccount
ca.crt
namespace
service-ca.crt
token

You can use the token to communicate with the OpenShift API. This is useful for when pods must communicate with the OpenShift API, for example in CI/CD pipelines. Refer to the Red Hat OpenShift Administration II: Operating a Production Kubernetes Cluster course for more details about configuring role-based access control (RBAC) and using service accounts.

Configure Security Context

Security context defines a set of constraints that influence how containers can interact with the underlying host system. This means that developers and administrators can manage privileges, user IDs, group IDs, linux capabilities, and other access control parameters at the container level.

In addition to security context, OpenShift uses Security Context Constraints (SCC) to set the security context automatically. Administrators can associate SCCs with roles and service accounts to apply the configuration to applications.

When you create a deployment that does not specify a security context, OpenShift generates a security context based on the applied SCC. However, the pod security admission plug-in displays a warning about the unrestricted capabilities of the pod:

[user@host ~]$ oc create deployment my-deployment \
--image registry.access.redhat.com/ubi8/ubi:8.0 -- sleep infinity
Warning: would violate PodSecurity "restricted:v1.24": allowPrivilegeEscalation != false (container "ubi" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "ubi" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "ubi" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "ubi" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")

The pod security admission plug-in currently attempts to read the security context before OpenShift generates it. You can verify that a pod has the restricted-v2 security context:

[user@host ~]$ oc get pod -o yaml | grep scc
      openshift.io/scc: restricted-v2

The restricted-v2 scc is the default SCC applied to the system:authenticated group.

Note

The OCPBUGS-7268 issue notes the warnings printed by the pod security admission plug-in as a bug, which is resolved in future versions of OpenShift.

You can implement the security context manually at the deployment level. To remove the preceding warning, your deployment must restrict the following capabilities:

  • allowPrivilegeEscalation

  • runAsNonRoot

  • seccompProfile

  • all capabilities

You can configure security context by using the .spec.template.spec.securityContext and .spec.template.spec.containers.securityContext objects, which is the pod configuration in the Deployment object:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: example
  strategy: {}
  template:
    metadata:
      labels:
        app: example
    spec:
      containers:
      - command:
        - sleep
        - infinity
        image: registry.access.redhat.com/ubi8/ubi:8.0
        name: ubi
        securityContext:
          runAsNonRoot: true
          allowPrivilegeEscalation: false
          seccompProfile:
            type: RuntimeDefault
          capabilities:
            drop:
            - ALL

Consequently, the security admission plug-in does not print the warning:

[user@host ~]$ oc create -f deployment.yaml
deployment.apps/example-deployment created

See the references section for more information about Kubernetes security contexts, and OpenShift SCCs.

Revision: do288-4.12-0d49506