Bookmark this page

Guided Exercise: Protect Internal Traffic with TLS

Configure two applications to connect securely inside the cluster by using TLS certificates that OpenShift manages.

Outcomes

  • Generate service certificates with the service-ca controller.

  • Mount a service certificate by using secrets.

  • Use a configuration map to inject a service certificate into a pod.

As the student user on the workstation machine, use the lab command to prepare your system for this exercise.

This command ensures that the OpenShift cluster is ready and creates the network-svccerts project and server deployment for the exercise. The command also creates a test pod named no-ca-bundle for use later in the exercise.

[student@workstation ~]$ lab start network-svccerts

Instructions

In this exercise, you work with the server deployment, which has an NGINX container that serves a "Hello World!" page with the HTTPS protocol. This deployment differs from earlier NGINX deployments, because it allows only the HTTPS protocol. The server application expects the existence of a certificate that you create in the exercise steps.

  1. Log in to the OpenShift cluster as the admin user and switch to the network-svccerts project.

    1. Use the oc login command to log in to api.ocp4.example.com:6443 as the admin user with the redhatocp password.

      [student@workstation ~]$ oc login -u admin -p redhatocp \
          https://api.ocp4.example.com:6443
      Login successful.
      
      ...output omitted...
    2. Use the oc project command to switch to the network-svccerts project.

      [student@workstation ~]$ oc project network-svccerts
      Now using project "network-svccerts" on server "https://api.ocp4.example.com:6443".
  2. Generate a service certificate and secret that are named server-secret for the server service, and then mount the secret in the server deployment.

    1. Annotate the server service with service.beta.openshift.io/serving-cert-secret-name=server-secret by using the oc annotate command. It automatically creates a secret named server-secret, which is populated with a signed TLS key and certificate.

      [student@workstation ~]$ oc annotate service server \
          service.beta.openshift.io/serving-cert-secret-name=server-secret
      service/server annotated
    2. Use the oc describe command to view the service and secret descriptions to verify that OpenShift created the secret.

      [student@workstation ~]$ oc describe service server
      ...output omitted...
      Annotations:       service.beta.openshift.io/serving-cert-secret-name: server-secret
                         service.beta.openshift.io/serving-cert-signed-by: openshift-service-serving-signer@1667565598
      ...output omitted...
      
      [student@workstation ~]$ oc describe secret server-secret
      Name:         server-secret
      Namespace:    network-svccerts
      ...output omitted...
      Type:  kubernetes.io/tls
      
      Data
      ====
      tls.key:  1675 bytes
      tls.crt:  2615 bytes
    3. Use a text editor to create a patch file to mount the server-secret secret in the server deployment. Edit the resource file at ~/DO280/labs/network-svccerts/server-secret.yaml. Replace the CHANGE_ME sections as shown in the following example:

      spec:
        template:
          spec:
            containers:
              - name: server
                volumeMounts:
                  - name: server-secret
                    mountPath: /etc/pki/nginx/
            volumes:
              - name: server-secret
                secret:
                  defaultMode: 420
                  secretName: server-secret
                  items:
                    - key: tls.crt
                      path: server.crt
                    - key: tls.key
                      path: private/server.key
    4. Apply the patch file to the server deployment with the oc patch command.

      [student@workstation ~]$ oc patch deployment server \
          --patch-file ~/DO280/labs/network-svccerts/server-secret.yaml
      deployment.apps/server patched
    5. Use the openssl s_client command in the no-ca-bundle pod to verify that OpenShift supplied the server deployment with a certificate. Verify that the no-ca-bundle pod needs to configure the CA that issued the OpenShift service certificate for certificate validation.

      [student@workstation ~]$ oc exec no-ca-bundle -- \
          openssl s_client -connect server.network-svccerts.svc:443
      depth=1 CN = openshift-service-serving-signer@1667565598
      CONNECTED(00000004)
      ---
      Certificate chain
       0 s:CN = server.network-svccerts.svc
         i:CN = openshift-service-serving-signer@1667565598
       1 s:CN = openshift-service-serving-signer@1667565598
         i:CN = openshift-service-serving-signer@1667565598
      ---
      ...output omitted...
      verify error:num=19:self signed certificate in certificate chain
      DONE

      Note

      The output shows the verify error:num=19:self signed certificate in certificate chain error, because the no-ca-bundle pod is not configured with the OpenShift cluster's CA bundle.

  3. Generate the ca-bundle configuration map that contains the service CA bundle, and use it to create the client pod.

    1. Create an empty configuration map named ca-bundle by using the oc create command.

      [student@workstation ~]$ oc create configmap ca-bundle
      configmap/ca-bundle created
    2. Annotate the ca-bundle configuration map with service.beta.openshift.io/inject-cabundle=true by using the oc annotate command.

      [student@workstation ~]$ oc annotate configmap ca-bundle \
          service.beta.openshift.io/inject-cabundle=true
      configmap/ca-bundle annotated
    3. View the YAML output of the ca-bundle configuration map to verify that the CA bundle is present.

      [student@workstation ~]$ oc get configmap ca-bundle -o yaml
      ...output omitted...
      data:
        service-ca.crt: |
          -----BEGIN CERTIFICATE-----
      ...output omitted...
    4. Use a text editor to add the ca-bundle configuration map to the client.yaml pod definition. Edit the resource file at ~/DO280/labs/network-svccerts/client.yaml. Replace the CHANGE_ME sections of the file as shown in the following example:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        annotations:
        labels:
          app: client
        name: client
        namespace: network-svccerts
      spec:
        replicas: 1
        selector:
          matchLabels:
            deployment: client
        strategy:
          rollingUpdate:
            maxSurge: 25%
            maxUnavailable: 25%
          type: RollingUpdate
        template:
          metadata:
            annotations:
              openshift.io/generated-by: OpenShiftNewApp
            labels:
              deployment: client
          spec:
            containers:
            - image: registry.ocp4.example.com:8443/redhattraining/hello-world-nginx
              imagePullPolicy: IfNotPresent
              name: client-deploy
              ports:
              - containerPort: 8080
                protocol: TCP
              volumeMounts:
              - mountPath: /etc/pki/ca-trust/extracted/pem
                name: trusted-ca
              terminationMessagePath: /dev/termination-log
              terminationMessagePolicy: File
            dnsPolicy: ClusterFirst
            restartPolicy: Always
            schedulerName: default-scheduler
            terminationGracePeriodSeconds: 30
            volumes:
              - configMap:
                  defaultMode: 420
                  name: ca-bundle
                  items:
                    - key: service-ca.crt
                      path: tls-ca-bundle.pem
                name: trusted-ca
            name: trusted-ca
    5. Apply the client.yaml file with the oc apply command to create the client pod.

      [student@workstation ~]$ oc apply -f ~/DO280/labs/network-svccerts/client.yaml
      ...output omitted...
      pod/client created
  4. Show that the server service is now accessible over HTTPS with a certificate that is signed by the OpenShift cluster.

    1. Use the curl command within the client pod to test that the server service is accessible on HTTPS.

      [student@workstation ~]$ oc exec deploy/client -- \
          curl -s https://server.network-svccerts.svc
      <html>
        <body>
          <h1>Hello, world from nginx!</h1>
        </body>
      </html>
    2. Use the openssl s_client command within the client pod to verify that the certificate is signed by the OpenShift cluster.

      [student@workstation ~]$ oc exec deploy/client -- \
          openssl s_client -connect server.network-svccerts.svc:443
      CONNECTED(00000004)
      ---
      Certificate chain
       0 s:CN = server.network-svccerts.svc
         i:CN = openshift-service-serving-signer@1667565598
       1 s:CN = openshift-service-serving-signer@1667565598
         i:CN = openshift-service-serving-signer@1667565598
      ---
      ...output omitted...
      verify return:1
      DONE

Finish

On the workstation machine, use the lab command to complete this exercise. This step is important to ensure that resources from previous exercises do not impact upcoming exercises.

[student@workstation ~]$ lab finish network-svccerts

Revision: do280-4.14-08d11e1