Skill Level: Intermediate

In this recipe, I demonstrate how to enable TLS termination for an application on IBM Cloud Private using the certificate manager service. This recipe will teach you how to deploy Ingress routing rules to expose an HTTP application over HTTPS.


To get started, you should have an elementary understanding of Kubernetes and have installed IBM Cloud Private version 3.1.1 into your development environment. In this tutorial I will demonstrate how to use the cert-manager shared service to create a certificate that will be used by the ingress to secure connections to a Jenkins server.


  1. Navigate to the web console for your ICP installation

    Open a web browser to the IBM Cloud Private management console at https://icp-address:8443. Login using your admin user id and password.

  2. Create a namespace for your deployment

    1. Open the menu in the IBM Cloud Private web console.
    2. Select the Manage group and then select the Namespaces page.
    3. Select the Create Namespace button
    4. Specify a name for the new namespace, in this example the name dev-deploys is used.
    5. Select the Create button
  3. Create a certificate in the new namespace

    The certificate will be used for TLS termination of the deployed application. The certificate manager shared service is used to create and manage the certificate. Details on creating certificates are available in the IBM Cloud Private Knowledge Center.

    1. Open a command window for the IBM Cloud Private installation by selecting the icon on the bottom right of the web console.
    2. Create a file named cert.yaml that contains the following contents which is provided as a sample certificate in the Knowledge Center.


    apiVersion: certmanager.k8s.io/v1alpha1
    kind: Certificate
    name: hello-deployment-tls-1
    namespace: foobar
    # name of the tls secret to store
    # the generated certificate/key pair
    secretName: hello-deployment-tls-1
    # ClusterIssuer Name
    name: icp-ca-issuer
    # Issuer can be referenced
    # by changing the kind here.
    # the default value is Issuer (i.e.
    # a locally namespaced Issuer)
    kind: ClusterIssuer
    commonName: "foo1.bar1"
    # one or more fully-qualified domain names
    # can be defined here
    - foo1.bar1


    Edit the lines in the sample certificate file as follows

    1. Specify a custom certificate name by updating the name field from hello-deployment-tls-1 to your customized value.
    2. Specify the correct namespace by updating the namespace value from foobar to the namespace created in step 2.
    3. Specify a custom secret name by updating the secretName field from hello-deployment-tls-1 to your customized value.
    4. Change the commonName field from foo1.bar1 to the host plus domain name used to access the application on this cluster.
    5. Change the entries under dnsNames so foo1.bar1 is no longer included but any other hosts that can be used to access the application must be added.
    6. Save the file and run the command:

      kubectl create -f cert.yaml

      to create the certificate.

    7. Validate the certificate was created successfully by running the command below substituting the namespace name you created previously for dev-deploys.

      kubectl describe certificate -n dev-deploys

      Validate the Status shows the certificate was created.

  4. Deploy your application

    This sample deploys the ibm-jenkins-dev chart, but you can extend this example to apply to other charts as well. Keep the command window open on the current browser window since it will continue to be used later. Open another browser window and access the IBM Cloud Private web console again from the new window.

    Install the ibm-jenkins-dev chart

    1. Select the Catalog link from the banner of the IBM Cloud Private web console
    2. Select the ibm-jenkins-dev chart
    3. Select the Configure button
    4. Specify a Helm release name
    5. Select the namespace created in step 2
    6. Select the checkbox to agree to the license agreement
    7. Under Parameters, select “All parameters” to expand all parameters.
    8. Unselect “Enable persistence for this deployment” since this sample install will not use persistence
    9. Select Install


    Validate the deployment completes successfully

    1. Select the View Helm Release link
    2. Wait a few minutes for the pod to change to the “Running” state
    3. Step 2 in the Notes at the bottom of the deployment page shows how to obtain the NodePort that can be used to access the jenkins server.  Run the listed command to obtain the port value.
    4. Open a new browser window and navigate to the URL http://<external_ip>:<port_value> where <port_value> is the port obtained in the previous step.
      Validate that you can access the jenkins server’s web console.
  5. Create an ingress for TLS termination

    Instead of accessing the jenkins server over HTTP, we want to provide a secure connection over HTTPS. This step creates the ingress definition necessary to expose the jenkins server over HTTPS. The HTTPS connection uses the certificate created in step 3.

    1. In the command window for IBM Cloud Private edit a new file named ingress.yaml
    2. Paste in the contents from the Ingress sample found in the Knowledge Center that is also included here:


    apiVersion: extensions/v1beta1
    kind: Ingress
    name: hello-k8s-ingress-tls
    kubernetes.io/ingress.class: "nginx"
    ingress.kubernetes.io/rewrite-target: "/"
    - hosts:
    - foo1.bar1
    secretName: hello-k8s-ingress-tls-1
    - host: foo1.bar1
    - backend:
    serviceName: hello-world-svc
    servicePort: 80
    path: /fb


    Make the following changes to the sample ingress

    1. Change the name field’s value from hello-k8s-ingress-tls to your custom value
    2. Add a namespace entry below the name similar to the entry below:

        namespace: dev-deploys

      Make sure you use your namespace name. In this sample the namespace is dev-deploys

    3. Below the “ -hosts” line, change the hostname foo1.bar1 to the common name that you used in your certificate
    4. Change the secretName to the name of the secret defined in the certificate’s secretName field from recipe step 3.
    5. Below the “ rules:” line, change the host entry from foo1.bar1 to the same value used under “ -hosts“.
    6. Change the serviceName to match the service name created by the deployment. The service name is based off of the helm release name you chose when you deployed the jenkins server.  Obtain the service name from the Service table listed on the deployment page for the helm chart.
    7. Change the servicePort value from 80 to 8080
    8. Change the path from /fb to /
    9. Save the changes
    10. Create the ingress with the command:

      kubectl create -f ingress.yaml

  6. Validate the ingress

    Make sure the ingress is working properly and is exposing the jenkins server using the certificate created for the ingress.

    1. Open a new web browser windows to https://<hostname>
    2. The jenkins login page appears
    3. Select the certificate from the browser and view its details to make sure it is the certificate that was defined in step 3
  7. Optional: Delete the NodePort to prevent HTTP access to the server

    At this point the jenkins server is exposed over HTTP and HTTPS at our external hostname. The ingress was used to expose the jenkins application over HTTPS. The service created by the deployment exposes jenkins over HTTP. Follow these steps to remove the HTTP access defined in the service.

    1. Using the command window, run this command to edit the service:

      kubectl edit service -n dev-deploys dev-jenkins-ibm-jenkins

      Change the dev-deploys namespace and the dev-jenkins-ibm-jenkins values shown above to your namespace and helm chart service name respectively.

    2. Change the value of the type field from NodePort to ClusterIP
    3. Delete the lines containing a nodePort field.
      Example: nodePort: 31714
    4. Save and quit the edit session


    Follow the steps below to make sure the service type was changed to ClusterIP successfully.

    1. From the IBM Cloud Private web console, select the Workloads menu entry and select Helm Release.
    2. Find the release you deployed for this sample and select the link for the release name.
    3. Click the link under Service and make sure the Type is ClusterIP.

Join The Discussion