Deploy on Kubernetes

EI Kubernetes (K8s) Operator

The EI Kubernetes operator (k8s-ei-operator) provides first-class support for Micro Integrator deployments in the Kubernetes ecosystem. It uses the Integration custom resource (integration_cr.yaml file) that is available in the Kubernetes project (exported from WSO2 Integration Studio) and deploys the integration in your Kubernetes environment.

The operator is configured with an NGINX Ingress controller by default, which exposes the deployed integration through HTTP. If required, you can use the operator's configuration mapper (config_map.yaml file) to disable the default Ingress controller and apply other configuration changes. Find out more about changing the default configurations of the EI K8s operator.

Prerequisites (system requirements)

Listed below are the system requirements for deploying integration solutions in Kubernetes using the EI K8s operator.

Info

The EI K8s Operator (k8s-ei-operator) is built with operator-sdk v0.7.0 and supported in the below environments.

Install the EI K8s Operator

Follow the steps given below to install the EI Kubernetes operator in your Kubernetes environment.

  1. Clone the latest k8s-ei-operator GitHub repository:

    git clone https://github.com/wso2/k8s-ei-operator.git
  2. Navigate to the k8s-ei-operator directory that you cloned:

    cd k8s-ei-operator
  3. Start your Kubernetes environment.

    Tip

    If you are using Minikube as your kubernetes environment, install and start Minikube.

  4. Set up the service account:

    kubectl create -f deploy/service_account.yaml
  5. Set up RBAC:

    kubectl create -f deploy/role.yaml
    kubectl create -f deploy/role_binding.yaml
  6. Deploy a custom resource definition, which enables a Kubernetes cluster to understand the custom resource type. The EI K8s operator introduces the Integration custom resource.

    kubectl create -f deploy/crds/integration_v1alpha1_integration_crd.yaml
  7. Deploy the k8s-ei-operator:

    kubectl create -f deploy/operator.yaml
  8. Apply the Ingress controller configurations to the config_map.yaml file (configuration mapping file):

    kubectl apply -f deploy/config_map.yaml
  9. Verify the installation by making sure that the following deployment is running in your Kubernetes cluster:

    kubectl get deployment
    
    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    k8s-ei-operator     1/1     1            1          1m

Your Kubernetes environment is now configured with the EI K8s operator. If required, you can configure the optional settings before using the operator.

Deploy integration solutions in K8s

Tip

To try the end-to-end process of deploying integration solutions on Kubernetes, see the K8s examples:

Given below are the main steps your will follow when you deploy integration solutions in a Kubernetes cluster.

  1. Be sure that the system requirements are fulfilled, and that the EI K8s operator is installed in your Kuberenetes environment.
  2. Your integration solution should be prepared using WSO2 Integration Studio as follows:

    1. Create the integration solution.
    2. Generate a Kubernetes project for the solution.
    3. Build the Docker image of your integration and push it to your Docker registry.
  3. Open the integration_cr.yaml file from the Kubernetes project in WSO2 Integration Studio.

  4. See that the details of your integration are correctly included in the file. See the example given below.

    apiVersion: "integration.wso2.com/v1alpha2"
    kind: "Integration"
    metadata:
      name: "hello-world"
    spec:
      replicas: 1
      image: "<Docker image for the Hello World Scenario>"

    Property Description
    kind The Integration kind represents the integration solution that will be deployed in the Kubernetes environment.
    metadata name The name of the integration solution.
    replicas The number of pods that should be created in the Kubernetes cluster.
    image Specify the Docker image of your integration solution. If you are using a Docker image from a private registry, you need to push the deployment as a Kuberntes secret. Follow the instructions in using a private registry image.

  5. Open a terminal, navigate to the location of your integration_cr.yaml file, and execute the following command to deploy the integration solution into the Kubernetes cluster:

    kubectl apply -f integration_cr.yaml

When the integration is successfully deployed, it should create the hello-world integration, hello-world-deployment, hello-world-service, and ei-operator-ingress as follows:

Tip

The ei-operator-ingress will not be created if you have disabled the ingress controller.

kubectl get integration

NAME          STATUS    SERVICE-NAME    AGE
hello-world   Running   hello-service   2m

kubectl get deployment

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
hello-world-deployment   1/1     1            1           2m

kubectl get services
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)       AGE
hello-world-service      ClusterIP   10.101.107.154   <none>        8290/TCP      2m
kubernetes               ClusterIP   10.96.0.1        <none>        443/TCP       2d
k8s-ei-operator          ClusterIP   10.98.78.238     <none>        443/TCP       1d

kubectl get ingress
NAME                  HOSTS     ADDRESS     PORTS     AGE
ei-operator-ingress   wso2ei    10.0.2.15   80, 443   2m

Use Docker images from private registries

The EI operator allows the use of any custom Docker image in a private registry as an integration solution. To achieve this, users have to pass the credentials to pull the image to the Kubernetes containers as a Kubernetes secret. The EI operator uses imagePullSecret to read the Kubernetes secret of the registry credentials.

  1. You can use the following command to create a Kubernetes secret with the credentials of the private Docker image:

    kubectl create secret docker-registry <secret-alias> --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-password> --docker-email=<your-email>

    Parameter Description
    secret-alias The name of the secret.
    your-registry-server The private Docker registry FQDN for DockerHub.
    your-name Your Docker user name.
    your-password Your Docker password.
    your-email You Docker email.

  2. Add the imagePullSecret property to the integration_cr.yaml custom resource file as follows:

    apiVersion: "integration.wso2.com/v1alpha2"
    kind: "Integration"
    metadata:
      name: "hello-world"
    spec:
      replicas: 1
      image: "<Docker image for the Hello World Scenario>"
      imagePullSecret: <secret-alias>
  3. You can now deploy the integration: Open a terminal and execute the following command from the location of your integration_cr.yaml file.

    kubectl apply -f integration_cr.yaml

View integration process logs

Once you have deployed your integrations in the Kubernetes cluster, see the output of the running integration solutions using the pod's logs.

  1. First, you need to get the associated pod id. Use the kubectl get pods command to list down all the deployed pods.

    kubectl get pods
    
    NAME                               READY   STATUS    RESTARTS   AGE
    hello-deployment-c68cbd55d-j4vcr   1/1     Running   0          3m
    k8s-ei-operator-6698d8f69d-6rfb6   1/1     Running   0          2d
  2. To view the logs of the associated pod, run the kubectl logs <pod name> command. This will print the output of the given pod ID.

    kubectl logs hello-deployment-c68cbd55d-j4vcr
    
    ...
    [2019-10-28 05:29:24,225]  INFO {org.wso2.micro.integrator.initializer.deployment.application.deployer.CAppDeploymentManager} - Successfully Deployed Carbon Application : HelloWorldCompositeApplication_1.0.0{super-tenant}
    [2019-10-28 05:29:24,242]  INFO {org.apache.synapse.transport.passthru.core.PassThroughListeningIOReactorManager} - Pass-through HTTP Listener started on 0.0.0.0:8290
    [2019-10-28 05:29:24,242]  INFO {org.apache.axis2.transport.mail.MailTransportListener} - MAILTO listener started
    [2019-10-28 05:29:24,250]  INFO {org.apache.synapse.transport.passthru.core.PassThroughListeningIOReactorManager} - Pass-through HTTPS Listener started on 0.0.0.0:8253
    [2019-10-28 05:29:24,251]  INFO {org.wso2.micro.integrator.initializer.StartupFinalizer} - WSO2 Micro Integrator started in 4 seconds

Invoke the integration solution

You can invoke the integration solution you deployed in Kubernetes using two methods.

Invoke using Ingress controller

Once you have deployed your integrations in the Kubernetes cluster, you can use the default Ingress controller in the deployment to invoke the solution:

  1. Obtain the External IP of the ingress load balancer using the kubectl get ingress command as follows:

    kubectl get ingress
    NAME                  HOSTS     ADDRESS     PORTS     AGE
    ei-operator-ingress   wso2ei    10.0.2.15   80, 443   2m
    For Minikube, you have to use the Minikube IP as the external IP. Hence, run minikube ip command to get the IP of the Minikube cluster.

  2. Add the HOST (wso2ei) and related ADDRESS (external IP) to the /etc/hosts file in your machine.

    Tip

    Note that the HOST of the Ingress controller is configured in the deploy/config_map.yaml file. The default host is wso2ei.

  3. Execute the following CURL command to run the hello-world service in Kubernetes:

    curl http://wso2ei/hello-world-service/services/HelloWorld

    You will receive the following response:

    {"Hello":"World"}%

Invoke without Ingress controller

Once you have deployed your integrations in the Kubernetes cluster, you can also invoke the integration solutions without going through the Ingress controller by using the port-forward method for services.

Follow the steps given below:

  1. Apply port forwarding:

    kubectl port-forward service/hello-world-service 8290:8290
  2. Invoke the proxy service:

    curl http://localhost:8290/services/HelloWorld

    You will receive the following response:

    {"Hello":"World"}%

Update existing integration deployments

The EI K8s operator allows you to update the Docker images used in Kubernetes pods(replicas) with the latest update of the tag. To pull the latest tag, we need to delete the associated pod with its pod ID as follows:

kubectl delete pod <POD-NAME>

When you run the above command, Kubernetes will spawn another temporary pod, which has the same behaviour of the pod we have deleted. Then the deleted pod will restart by pulling the latest tag from the Docker image path.

Note

Here we are recommending to use a different image path for the updated integration solution. Otherwise, (because the Docker image is re-pulled from the existing deployment) some traffic from outside might get lost.

Configure the EI K8s Operator (Optional)

See the topics given below to update/change the default configurations of the EI K8s operator.

Disable Ingress controller

By default, the EI operator creates an NGINX ingress through which it exposes HTTP/HTTPS transport protocols. If user needs to create a deployment without the default ingress:

  1. Open the config_map.yaml file.
  2. Change the autoIngressCreation property value to false in the ei-operator-config config mapping as follows.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ei-operator-config
    data:
      host: wso2ei
      autoIngressCreation: "false" 

Enable HTTPS for the integration solution

We can use the ingressTLS property in the configuration mapping of the operator to expose an ingress NGINX HTTPS transport of your integration application in Kubernetes. If a user has defined ingressTLS in the configuration mapping, the ingress controller uses this TLS and terminates with the given HTTP.

ingressTLS: wso2-tls

Follow the steps given below.

  1. You need to generate a self-signed certificate and private key using the following command. For more details about certificate creation, see this link.

    openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout wso2.key -out wso2.crt -subj "/CN=wso2/O=wso2"

  2. Create a Kubernetes secret called wso2-tls by executing the following command:

    kubectl create secret tls wso2-tls --key wso2.key --cert wso2.crt

  3. Open the config_map.yaml file, and add this secret alias called wso2-tls to the ei-operator-config configuration mapping as follows:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ei-operator-config
    data:
      host: wso2ei
      autoIngressCreation: "false" 
      ingressTLS: wso2-tls

Now, you can invoke the deployed applications from following URL format.

https://<HOST-NAME>/<SERVICE-NAME>/<SERVICE-CONTEXT>

For the Hello World example, the request should be as follows:

curl --cacert wso2.crt https://wso2ei/hello-world-service/services/HelloWorld

You will receive the following response:

{"Hello":"World"}%

Enable both HTTP and HTTPS

If you have enabled HTTPS for the Ingress controller, the ingress controller redirects HTTP requests to the HTTPS port (443), by default, using a 308 Permanent Redirect response. To allow both HTTP and HTTPS requests, we can update the configuration mapping by adding the following property:

sslRedirect: "false"
  1. Open the config_map.yaml file.
  2. Update the ei-operator-config configuration mapping:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ei-operator-config
    data:
      host: wso2ei
      autoIngressCreation: "false" 
      ingressTLS: wso2-tls
      sslRedirect: "false"

Run inbound endpoints

Inbound Endpoints in the Micro Integrator are used for separating endpoint listeners. That is, for each HTTP inbound endpoint, messages are handled separately. Also, we can create any number of inbound endpoints on any port.

Therefore, we can expose the inbound endpoint ports from the Kubernetes cluster by passing the inboundPorts property inside our integration_cr.yaml custom resource file as follows:

apiVersion: "integration.wso2.com/v1alpha2"
kind: "Integration"
metadata:
  name: "inbound-samples"
spec:
  replicas: 1
  image: "<Docker image for the inbound endpoint Scenario>"
  inboundPorts:
    - 8000
    - 9000
    ... 

Use the following methods to invoke the inbound endpoints in HTTP and HTTPS transports. Note that <INTEGRATION-NAME> is the value we have used as the metadata name in the integration_cr.yaml file.

  • HTTP request

    curl http://<HOST-NAME>/<INTEGRATION-NAME>-inbound/<PORT>/<CONTEXT>
  • HTTPS request

    curl --cacert <CERT_FILE> https://<HOST-NAME>/<INTEGRATION-NAME>-inbound/<PORT>/<CONTEXT>
Top