Skip to main content
Skip table of contents

Tutorial - Deploy Istio and cert-manager with Helm to Issue Mesh Certificates from EJBCA

In this tutorial, you will learn how to deploy Istio and cert-manager with Helm to issue mesh certificates from EJBCA.

In the previous tutorial, Deploy EJBCA container to issue certificates to an Istio service mesh, service mesh certificates were issued with the EJBCA csr-api solution. This tutorial covers another way to issue service mesh certificates for Istio using cert-manager. It shows you how to deploy cert-manager and Istio using Helm charts to issue mTLS certificates from EJBCA.

The tutorial covers these steps: 

  • Create certificate profile and end entity profile

  • Update the cert-manager RA Role

  • Deploy cert-manager with Helm

  • Deploy istio-csr with Helm

  • Deploy Istio with Helm

  • Deploy Istio sample application

Prerequisites

For this tutorial, EJBCA Community container version 8.2.0.1 was used.

Before you begin, you need:

A running EJBCA instance – Click here to learn more.
A running EJBCA instance - Click to learn more

If you don’t already have EJBCA installed, here are some options for you:

Step 1 - Create Certificate Profile and End Entity Profile

This tutorial will use a new certificate profile and end entity profile for issuing the mesh certificates. The certificates will be ephemeral and are not stored in the database. To configure these new profiles, follow these steps:

  1. Login to EJBCA Administration.

  2. Click Certificate Profiles under CA Functions.

  3. Click Clone next to the ephemeralMtls-14d certificate profile.

  4. Name the new certificate profile ephemeralClientServer-3d, and click Create from template.

  5. To edit the profile values to fit your needs, find the newly created ephemeralClientServer-3d displayed in the list and click Edit.

  6. On the Edit page, update the following:

    • For Validity or end date of the certificate, enter 3d.

    • For Extended Key Usage, select Server Authentication in addition to Client Authentication.

  7. Click Save to store the certificate profile.

  8. Next, to create an end entity profile, in the EJBCA menu, click End Entity Profiles under RA Functions.

  9. Select ephemeralMtls, enter ephemeralSpiffe in the Add End Entity Profile field, and click Clone selected.

  10. Select the newly created ephemeralSpiffe, and click Edit End Entity Profile to update the profile.

  11. Edit the profile and update the following:

    • In the Subject DN Attributes list, select CN, Common Name, and click Add.

    • In the Other Subject Attributes section, clear Required for DNS Name.

    • For Subject Alternative Name, select DNS Name in the list, and click Add two (2) times.

    • For Subject Alternative Name, select Uniform Resource Identifier (URI), and click Add two (2) times.

    • For Available Certificate Profiles, select ephemeralClientServer-3d in addition to the ephemeralMtls-14.

    • For the Available CAs, select MyPKISubCA-G1 in addition to ephemeralSubCA-G1.

  12. Click Save at the bottom of the page.

You have now configured a new certificate profile and end entity profile to use for issuing the mesh certificates. Continue to the next step to update the RA-cert-manager role to use this new end entity profile.

Step 2 - Update the cert-manager RA Role

Update the RA-cert-manager role to use the end entity profile created in the previous step and add the Ephemeral Sub CA. To update the role, follow these steps:

  1. In the EJBCA menu, under System Functions, click Roles and Access Rules.

  2. Click Access Rules for the RA-cert-manager role.

  3. Edit the access rules according to the following:

    • For Authorized CAs, select the ephemeralSubCA-G1 in addition to the MyPKISubCA-G1.

    • For End Entity Profiles, select ephemeralSpiffe in addition to the TLS Client Profile and TLS Server Profile.

  4. Click Save to store the updated access rules.

You have now updated the RA-cert-manager role. Continue to the next step to deploy cert-manager using Helm.

Step 3 - Deploy cert-manager with Helm

cert-manager is used to issue and manage certificates in the Kubernetes cluster. To deploy cert-manager using Helm, follow these steps:

  1. SSH to the Kubernetes host.

  2. Change directories to the cert-manager directory:

BASH
$ cd cert-manager
  1. Create the cert-manager namespace for the EJBCA cert-manager issuer and cert-manager:

BASH
$ kubectl create namespace cert-manager
  1. The output is similar to the following:

BASH
namespace/cert-manager created
  1. Create a secret for the cert-manager-ra-01 credential:

BASH
$ kubectl -n cert-manager create secret tls ejbca-secret --cert=cert-manager-ra-01.crt --key=cert-manager-ra-01-key.pem
  1. The output is similar to the following:

BASH
secret/ejbca-secret created
  1. Create the ejbca-ca-secret secret for the EJBCA TLS chain:

BASH
$ kubectl -n cert-manager create secret generic ejbca-ca-secret --from-file=ca.crt=ManagementCA.crt
  1. The output is similar to the following:

BASH
secret/ejbca-ca-secret created
  1. Update the Helm repository cache:

BASH
$ helm repo update

(warning) Note: If the cert-manager helm repository is not installed, install the repository with the following command:
helm repo add jetstack https://charts.jetstack.io

  1. The output is similar to the following:

BASH
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "ejbca-issuer" chart repository
...Successfully got an update from the "ejbca-ce" chart repository
...Successfully got an update from the "hashicorp" chart repository
...Successfully got an update from the "jetstack" chart repository
...Successfully got an update from the "groundhog2k" chart repository
Update Complete. ⎈Happy Helming!⎈
  1. Install the Custom Resource Definitions (CRD) for cert-manager:

BASH
$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.0/cert-manager.crds.yaml
  1. The output is similar to the following:

BASH
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io created
  1. Deploy cert-manager using Helm:

BASH
$ helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --version v1.15.0
  1. The output is similar to the following:

BASH
NAME: cert-manager
LAST DEPLOYED: Thu Jun 13 15:38:25 2024
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager v1.15.0 has been deployed successfully!

In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).

More information on the different types of issuers and how to configure them
can be found in our documentation:

https://cert-manager.io/docs/configuration/

For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:

https://cert-manager.io/docs/usage/ingress/
  1. Deploy the EJBCA cert-manager issuer using Helm:

BASH
$ helm install -n cert-manager ejbca-cmi ejbca-issuer/ejbca-cert-manager-issuer --set image.tag="1.4.0"
  1. The output is similar to the following:

BASH
NAME: ejbca-cmi
LAST DEPLOYED: Thu Jun 13 15:39:11 2024
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None
  1. Create the ejbca-node1-svc.yaml file:

BASH
$ cat > ../k81/ejbca-node1-svc.yaml <<EOF 
apiVersion: v1
kind: Service
metadata:
  name: ejbca-node1
  namespace: ejbca-k8s
  labels:
    app.kubernetes.io/name: ejbca-ca
spec:
  type: ClusterIP
  ports:
  - name: https
    port: 443
    targetPort: nginx-https
  - name: http
    port: 80
    targetPort: nginx-http
  selector:
    app.kubernetes.io/name: ejbca-ca
    app.kubernetes.io/instance: ejbca-ca

EOF
  1. Apply the ejbca-node1-svc.yaml file:

BASH
$ kubectl apply -f ../k81/ejbca-node1-svc.yaml
  1. The output is similar to the following:

BASH
service/ejbca-node1 created
  1. Create the istio-system namespace that is used by Istio:

BASH
$ kubectl create namespace istio-system 
  1. The output is similar to the following:

BASH
namespace/istio-system  created
  1. Create the issuer-ephemeralCA-spiffe-istio-system.yaml file:

BASH
$ cat > issuer-ephemeralCA-spiffe-istio-system.yaml <<EOF 
apiVersion: ejbca-issuer.keyfactor.com/v1alpha1
kind: Issuer
metadata:
  namespace: istio-system
  labels:
    # Customize to to your deployment, but these are optional
    app.kubernetes.io/name: issuer
    app.kubernetes.io/instance: istio-system-spiffe
    app.kubernetes.io/part-of: ejbca-issuer
    app.kubernetes.io/created-by: ejbca-issuer
  name: istio-system-spiffe
spec:
  hostname: "ejbca-node1.ejbca-k8s"
  ejbcaSecretName: "ejbca-secret"
  certificateAuthorityName: "ephemeralSubCA-G1"
  certificateProfileName: "ephemeralClientServer-3d"
  endEntityProfileName: "ephemeralSpiffe"
  caBundleSecretName: ejbca-ca-secret 

EOF
  1. Apply the issuer-ephemeralCA-spiffe-istio-system.yaml file:

BASH
$ kubectl apply -f issuer-ephemeralCA-spiffe-istio-system.yaml
  1. The output is similar to the following:

BASH
issuer.ejbca-issuer.keyfactor.com/istio-system-spiffe created
  1. Describe the istio-system issuer:

BASH
$ kubectl -n istio-system describe issuers.ejbca-issuer.keyfactor.com
  1. The output is similar to the following:

BASH
Name:         istio-system-spiffe
Namespace:    istio-system
Labels:       app.kubernetes.io/created-by=ejbca-issuer
              app.kubernetes.io/instance=istio-system-spiffe
              app.kubernetes.io/name=issuer
              app.kubernetes.io/part-of=ejbca-issuer
Annotations:  <none>
API Version:  ejbca-issuer.keyfactor.com/v1alpha1
Kind:         Issuer
Metadata:
  Creation Timestamp:  2024-06-13T19:40:26Z
  Generation:          1
  Resource Version:    9179
  UID:                 0b315d8f-5d5b-4922-91fe-ab4aaa5331d2
Spec:
  Ca Bundle Secret Name:       ejbca-ca-secret
  Certificate Authority Name:  ephemeralSubCA-G1
  Certificate Profile Name:    ephemeralClientServer-3d
  Ejbca Secret Name:           ejbca-secret
  End Entity Profile Name:     ephemeralSpiffe
  Hostname:                    ejbca-node1.ejbca-k8s
Status:
  Conditions:
    Last Transition Time:  2024-06-13T19:40:26Z
    Message:               Success
    Reason:                ejbca-issuer.IssuerController.Reconcile
    Status:                True
    Type:                  Ready
Events:                    <none>
  1. Create the ejbca-cmi-role.yaml that is used for auto-approval of certificates issued from the pkimesh1 issuer:

BASH
$ cat > ./ejbca-cmi-role.yaml <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com
rules:
  - verbs:
      - approve
    apiGroups:
      - cert-manager.io
    resources:
      - signers
    resourceNames:
      - issuers.ejbca-issuer.keyfactor.com/*
      # Uncomment if you are using a cluster issuer in addition to an issuer
      #- clusterissuers.ejbca-issuer.keyfactor.com/*

EOF
  1. Apply the ejbca-cmi-role.yaml file:

BASH
$ kubectl apply -f ejbca-cmi-role.yaml
  1. The output is similar to the following:

BASH
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com created
  1. Create the ejbca-cmi-rb.yaml file that creates a role binding for the auto-approve role:

BASH
$ cat > ./ejbca-cmi-rb.yaml <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com
subjects:
  - kind: ServiceAccount
    name: cert-manager
    namespace: cert-manager
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com

EOF
  1. Apply the ejbca-cmi-rb.yaml file:

BASH
$ kubectl apply -f ejbca-cmi-rb.yaml
  1. The output is similar to the following:

BASH
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com created

The cert-manager and EJBCA cert-manager issuer are now deployed and configured in the Kubernetes cluster. Continue to the next step to deploy the cert-manager istio-csr.

Step 4 - Deploy istio-csr with Helm

For the CSRs created from Istio to be signed by an external cert-manager issuer, the cert-manager istio-csr component must be deployed. To deploy the cert-manager istio-csr using Helm, follow theses steps:

  1. Download the CA chain for the ephemeralSubCA-G1 Issuing CA:

BASH
$ curl -X GET --cert ~/cert-manager/cert-manager-ra-01.crt \
--key ~/cert-manager/cert-manager-ra-01-key.pem \
--cacert ~/ca.crt "https://ejbca-node1.ejbca-k8s/ejbca/ra/cert?caid=873652977&chain=true&format=pem" \
-H "accept: */*" -o ephemeralSubCA-G1-chain.pem

(warning) Note: The URL is obtained from the RA Web CA Certificate and CRLs in the top menu. Right-click the Certificate chain PEM, and select Copy Link.

  1. The output is similar to the following:

BASH
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1372  100  1372    0     0   133k      0 --:--:-- --:--:-- --:--:--  133k
  1. Create the istio-root-ca secret for the CA chain certificates:

BASH
$ kubectl create secret generic -n cert-manager istio-root-ca --from-file=ca.pem=ephemeralSubCA-G1-chain.pem
  1. The output is similar to the following:

BASH
secret/istio-root-ca created
  1. Deploy istio-csr using Helm:

BASH
$ helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr --wait\
  --set "app.certmanager.issuer.group=ejbca-issuer.keyfactor.com" \
  --set "app.certmanager.issuer.kind=Issuer" \
  --set "app.certmanager.issuer.name=istio-system-spiffe" \
  --set "app.certmanager.preserveCertificateRequests=false" \
  --set "app.server.serving.signatureAlgorithm=ECDSA" \
  --set "app.tls.istiodPrivateKeySize=256" \
  --set "app.server.serving.certificateKeySize=256" \
  --set "app.server.maxCertificateDuration=48h" \
  --set "app.tls.certificateDuration=24h" \
  --set "app.tls.istiodCertificateDuration=24h" \
  --set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \
  --set "volumeMounts[0].name=root-ca" \
  --set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \
  --set "volumes[0].name=root-ca" \
  --set "volumes[0].secret.secretName=istio-root-ca"
  1. The output is similar to the following:

BASH
NAME: cert-manager-istio-csr
LAST DEPLOYED: Thu Jun 13 15:43:58 2024
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None

cert-manager istio-csr is now deployed using Helm. Continue to the next step to deploy the Istio components using Helm.

Step 5 - Deploy Istio with Helm

Now that all the cert-manager pieces are in place to handle certificate issuance using EJBCA in the Kubernetes cluster, it is time to deploy Istio using Helm. To deploy Istio, follow these steps:

  1. Install the Istio helm repository:

BASH
$ helm repo add istio https://istio-release.storage.googleapis.com/charts
  1. The output is similar to the following:

BASH
"istio" has been added to your repositories
  1. Deploy Istio base using Helm:

BASH
$ helm install istio-base istio/base -n istio-system --set defaultRevision=default
  1. The output is similar to the following:

BASH
NAME: istio-base
LAST DEPLOYED: Thu Jun 13 15:44:57 2024
NAMESPACE: istio-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Istio base successfully installed!

To learn more about the release, try:
  $ helm status istio-base -n istio-system
  $ helm get all istio-base -n istio-system
  1. Deploy the Istio CNI container using Helm:

BASH
$ helm install istio-cni istio/cni -n kube-system --wait\
  --set "cni.cniBinDir=/var/snap/microk8s/current/opt/cni/bin" \
  --set "cni.cniConfDir=/var/snap/microk8s/current/args/cni-network"

(warning) Note: If you are not using a CNI (Project Calico, ETC) in your Kubernetes deployment, do not deploy the istio-cni helm chart.

  1. The output is similar to the following:

BASH
NAME: istio-cni
LAST DEPLOYED: Thu Jun 13 15:45:20 2024
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
"istio-cni" successfully installed!

To learn more about the release, try:
  $ helm status istio-cni -n kube-system
  $ helm get all istio-cni -n kube-system
  1. Create the istio-overide.yaml file to deploy Istio with the settings needed to use cert-manager:

BASH
$ cat > ./istio-override.yaml <<EOF 
defaults:
  ## Discovery Settings
  pilot:
    autoscaleEnabled: true
    autoscaleMin: 1
    autoscaleMax: 5
    autoscaleBehavior: {}
    replicaCount: 1
    rollingMaxSurge: 100%
    rollingMaxUnavailable: 25%
    hub: ""
    tag: ""
    variant: ""
    image: pilot
    traceSampling: 1.0
    # Resources for a small pilot install
    resources:
      requests:
        cpu: 500m
        memory: 2048Mi
    seccompProfile: {}
    cni:
      repair:
        enabled: true
      enabled: true
      provider: default
    extraContainerArgs:
      - --tlsCertFile=/etc/cert-manager/tls/tls.crt
      - --tlsKeyFile=/etc/cert-manager/tls/tls.key
      - --caCertFile=/etc/cert-manager/ca/root-cert.pem
    env:
      ENABLE_CA_SERVER: false
    taint:
      enabled: false
      namespace: ""
    affinity: {}
    tolerations: []
    cpu:
      targetAverageUtilization: 80
    memory: {}
    # Additional volumeMounts to the istiod container
    volumeMounts:
      - name: cert-manager
        mountPath: /etc/cert-manager/tls
        readOnly: true
      - name: istio-csr-ca-configmap
        mountPath: /etc/cert-manager/ca
        readOnly: true
    # Additional volumes to the istiod pod
    volumes:
      - name: cert-manager
        secret:
          defaultMode: 420
          secretName: istiod-tls
      - name: ca-root-cert
        configMap:
          name: istio-ca-root-cert
          optional: true
          defaultMode: 420
    nodeSelector: {}
    podAnnotations: {}
    serviceAnnotations: {}
    serviceAccountAnnotations: {}
    topologySpreadConstraints: []
    jwksResolverExtraRootCA: ""
    configSource:
      subscribedResources: []
    keepaliveMaxServerConnectionAge: 30m
    deploymentLabels: {}
    configMap: true
    podLabels: {}
    ipFamilyPolicy: ""
    ipFamilies: []
  sidecarInjectorWebhook:
    neverInjectSelector: []
    alwaysInjectSelector: []
    injectedAnnotations: {}
    enableNamespacesByDefault: false
    reinvocationPolicy: Never
    rewriteAppHTTPProbe: true
    templates: {}
    defaultTemplates: []
  istiodRemote:
    injectionURL: ""
    injectionPath: "/inject"
    injectionCABundle: ""
  telemetry:
    enabled: true
    v2:
      enabled: true
      prometheus:
        enabled: true
      stackdriver:
        enabled: false
  revision: ""
  revisionTags: []
  ownerName: ""
  meshConfig:
    defaultConfig:
      trustDomain: cluster.local
      proxyMetadata:
        ECC_SIGNATURE_ALGORITHM: ECDSA
    enablePrometheusMerge: true
  experimental:
    stableValidationPolicy: false
  global:
    istioNamespace: istio-system
    certSigners:
      - issuers.ejbca-issuer.keyfactor.com/pkimesh1-spiffe
      - issuers.ejbca-issuer.keyfactor.com/istio-system-spiffe
    defaultPodDisruptionBudget:
      enabled: true
    defaultResources:
      requests:
        cpu: 10m
      #   memory: 128Mi
      # limits:
      #   cpu: 100m
      #   memory: 128Mi
    hub: docker.io/istio
    tag: 1.22.1
    variant: ""
    imagePullPolicy: ""
    imagePullSecrets: []
    istiod:
      enableAnalysis: false
    logAsJson: false
    logging:
      level: "default:info"
    omitSidecarInjectorConfigMap: false
    operatorManageWebhooks: false
    priorityClassName: ""
    proxy:
      image: proxyv2
      autoInject: enabled
      clusterDomain: "cluster.local"
      componentLogLevel: "misc:error"
      enableCoreDump: false
      excludeInboundPorts: ""
      includeInboundPorts: "*"
      includeIPRanges: "*"
      excludeIPRanges: ""
      includeOutboundPorts: ""
      excludeOutboundPorts: ""
      # Log level for proxy, applies to gateways and sidecars.
      # Expected values are: trace|debug|info|warning|error|critical|off
      logLevel: warning
      privileged: false
      readinessFailureThreshold: 4
      readinessInitialDelaySeconds: 0
      readinessPeriodSeconds: 15
      startupProbe:
        enabled: true
        failureThreshold: 600 # 10 minutes
      # Resources for the sidecar.
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 2000m
          memory: 1024Mi
      statusPort: 15020
      tracer: "none"
    proxy_init:
      image: proxyv2
    remotePilotAddress: ""
    caAddress: "cert-manager-istio-csr.cert-manager.svc:443"
    externalIstiod: false
    configCluster: false
    configValidation: true
    meshID: ""
    meshNetworks: {}
    # Use the user-specified, secret volume mounted key and certs for Pilot and workloads.
    mountMtlsCerts: false
    multiCluster:
      enabled: false
      clusterName: ""
    network: ""
    pilotCertProvider: istiod
    sds:
      token:
        aud: istio-ca
    sts:
      servicePort: 0
    # The name of the CA for workload certificates.
    # For example, when caName=GkeWorkloadCertificate, GKE workload certificates
    # will be used as the certificates for workloads.
    # The default value is "" and when caName="", the CA will be configured by other
    # mechanisms (e.g., environmental variable CA_PROVIDER).
    caName: ""
    autoscalingv2API: true
  base:
    enableIstioConfigCRDs: true
  istio_cni:
    chained: true
    provider: default

EOF

(warning) Note: If you are not using a CNI (Project Calico, ETC) in your Kubernetes deployment, you will need to set cni.enabled to false.

  1. Deploy Istiod using Helm:

BASH
$ helm -n istio-system install istiod istio/istiod --wait -f istio-override.yaml
  1. The output is similar to the following:

BASH
NAME: istiod
LAST DEPLOYED: Thu Jun 13 15:45:49 2024
NAMESPACE: istio-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
"istiod" successfully installed!

To learn more about the release, try:
  $ helm status istiod -n istio-system
  $ helm get all istiod -n istio-system

Next steps:
  * Deploy a Gateway: https://istio.io/latest/docs/setup/additional-setup/gateway/
  * Try out our tasks to get started on common configurations:
    * https://istio.io/latest/docs/tasks/traffic-management
    * https://istio.io/latest/docs/tasks/security/
    * https://istio.io/latest/docs/tasks/policy-enforcement/
  * Review the list of actively supported releases, CVE publications and our hardening guide:
    * https://istio.io/latest/docs/releases/supported-releases/
    * https://istio.io/latest/news/security/
    * https://istio.io/latest/docs/ops/best-practices/security/

For further documentation see https://istio.io website

The Istio components are now deployed using Helm charts. Continue to the next step to deploy the sample application and test the connectivity between pods.

Step 6 - Deploy Istio sample application

cert-manager and Istio are now deployed and configured in the Kubernetes cluster and ready to use. To deploy the Istio sample applications to test the mesh, follow these steps:

  1. Create the pkimesh1 namespace that is used by Istio sample applications:

BASH
$ kubectl create namespace pkimesh1
  1. The output is similar to the following:

BASH
namespace/pkimesh1 created
  1. Enable istio-injection in the pkimesh1 namespace:

BASH
$ kubectl label namespace pkimesh1 istio-injection=enabled --overwrite
  1. The output is similar to the following:

BASH
namespace/pkimesh1 labeled
  1. Deploy the Istio httpbin sample application:

BASH
$ kubectl apply -n pkimesh1 -f https://raw.githubusercontent.com/istio/istio/1.22.1/samples/httpbin/httpbin.yaml
  1. The output is similar to the following:

BASH
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created
  1. Deploy the Istio sleep sample application:

BASH
$ kubectl apply -n pkimesh1 -f https://raw.githubusercontent.com/istio/istio/1.22.1/samples/sleep/sleep.yaml
  1. The output is similar to the following:

BASH
service/sleep created
deployment.apps/sleep created
  1. Review what resources are in the pkimesh1 namespace:

BASH
$ kubectl -n pkimesh1 get all
  1. The output is similar to the following:

BASH
NAME                           READY   STATUS    RESTARTS   AGE
pod/httpbin-86b8ffc5ff-wxkd2   2/2     Running   0          118s
pod/sleep-7656cf8794-rqzqt     2/2     Running   0          90s

NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/httpbin   ClusterIP   10.152.183.110   <none>        8000/TCP   118s
service/sleep     ClusterIP   10.152.183.36    <none>        80/TCP     90s

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/httpbin   1/1     1            1           118s
deployment.apps/sleep     1/1     1            1           90s

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/httpbin-86b8ffc5ff   1         1         1       118s
replicaset.apps/sleep-7656cf8794     1         1         1       90s
  1. Test the communication between the two applications that are in the mesh:

BASH
$ export SLEEP_POD_FOO=$(kubectl get pod -n pkimesh1 -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec "$SLEEP_POD_FOO" -n pkimesh1 -c sleep -- curl --silent http://httpbin.pkimesh1:8000/html
  1. The output is similar to the following:

BASH
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
      <h1>Herman Melville - Moby-Dick</h1>

      <div>
        <p>
          Availing himself of the mild, summer-cool weather that now reigned in these latitudes, and in preparation for the peculiarly active pursuits shortly to be anticipated, Perth, the begrimed, blistered old blacksmith, had not removed his portable forge to the hold again, after concluding his contributory work for Ahab's leg, but still retained it on deck, fast lashed to ringbolts by the foremast; being now almost incessantly invoked by the headsmen, and harpooneers, and bowsmen to do some little job for them; altering, or repairing, or new shaping their various weapons and boat furniture. Often he would be surrounded by an eager circle, all waiting to be served; holding boat-spades, pike-heads, harpoons, and lances, and jealously watching his every sooty movement, as he toiled. Nevertheless, this old man's was a patient hammer wielded by a patient arm. No murmur, no impatience, no petulance did come from him. Silent, slow, and solemn; bowing over still further his chronically broken back, he toiled away, as if toil were life itself, and the heavy beating of his hammer the heavy beating of his heart. And so it was.—Most miserable! A peculiar walk in this old man, a certain slight but painful appearing yawing in his gait, had at an early period of the voyage excited the curiosity of the mariners. And to the importunity of their persisted questionings he had finally given in; and so it came to pass that every one now knew the shameful story of his wretched fate. Belated, and not innocently, one bitter winter's midnight, on the road running between two country towns, the blacksmith half-stupidly felt the deadly numbness stealing over him, and sought refuge in a leaning, dilapidated barn. The issue was, the loss of the extremities of both feet. Out of this revelation, part by part, at last came out the four acts of the gladness, and the one long, and as yet uncatastrophied fifth act of the grief of his life's drama. He was an old man, who, at the age of nearly sixty, had postponedly encountered that thing in sorrow's technicals called ruin. He had been an artisan of famed excellence, and with plenty to do; owned a house and garden; embraced a youthful, daughter-like, loving wife, and three blithe, ruddy children; every Sunday went to a cheerful-looking church, planted in a grove. But one night, under cover of darkness, and further concealed in a most cunning disguisement, a desperate burglar slid into his happy home, and robbed them all of everything. And darker yet to tell, the blacksmith himself did ignorantly conduct this burglar into his family's heart. It was the Bottle Conjuror! Upon the opening of that fatal cork, forth flew the fiend, and shrivelled up his home. Now, for prudent, most wise, and economic reasons, the blacksmith's shop was in the basement of his dwelling, but with a separate entrance to it; so that always had the young and loving healthy wife listened with no unhappy nervousness, but with vigorous pleasure, to the stout ringing of her young-armed old husband's hammer; whose reverberations, muffled by passing through the floors and walls, came up to her, not unsweetly, in her nursery; and so, to stout Labor's iron lullaby, the blacksmith's infants were rocked to slumber. Oh, woe on woe! Oh, Death, why canst thou not sometimes be timely? Hadst thou taken this old blacksmith to thyself ere his full ruin came upon him, then had the young widow had a delicious grief, and her orphans a truly venerable, legendary sire to dream of in their after years; and all of them a care-killing competency.
        </p>
      </div>
  </body>

The sample application demonstrates that connectivity between the pods in the mesh is successful. This completes the tutorial for using EJBCA with cert-manager and Istio deployed using Helm to issue certificates in the Istio mesh.

Next steps

In this tutorial, you learned how to configure EJBCA to issue a new certificate type for the cert-manager / Istio integration, deploy cert-manager and Istio using Helm, and test the communication with the Istio sample application.

Here are some next steps we recommend:

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.