WebSphere Application Server & Liberty

 View Only

Deploy sample Daytrader7 application to WebSphere Liberty on Amazon Elastic Kubernetes Service (EKS)

By Barbara Jones posted Thu March 23, 2023 03:30 PM

  

This article will show how to deploy sample Daytrader7 application to an Amazon Elastic Kubernetes Service (EKS) using the WebSphere Liberty Operator (WLO).  For more information about the WebSphere Liberty Operator, see blog.


Prerequisites

As part of the prerequisite steps, an EKS cluster has been created and proper permissions have been assigned to allow access to the cluster.  That cluster will be referenced and remotely connected to from the local command line in this article.  In order to allow interaction with AWS and the EKS cluster using the AWS Command Line Interface (AWS CLI), a few additional configuration commands might be needed.

Configure your AWS and EKS command line

Configure your AWS CLI


To configure some basic settings such as credentials and regions for interaction with the AWS CLI on the local environment, use the aws configure command.  

# aws configure

AWS Access Key ID [None]: <access key id>
AWS Secret Access Key [None]: <secret access key>
Default region name [None]: <cluster's region>
Default output format [None]: <will default to json if nothing entered>

Create/update your EKS cluster configuration


Next create a kubeconfig file that stores credentials for the Kubernetes cluster on EKS. 

# aws eks update-kubeconfig --name <cluster-name>

 

Creating an Ingress for the EKS cluster

Configure Nginx ingress controller and create an alias record

To expose applications externally later when they are installed on the cluster, install an NGINX ingress controller.  There are other options that could also be explored for this such as a simple load balancer or another ingress like AWS Load Balancer Controller add-on.

The following command will install a basic NGINX ingress on the cluster.

# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.6.4/deploy/static/provider/aws/deploy.yaml


Once the Nginx installation is complete, create an alias record (an ‘A’ record) that points to the load balancer that was created during the NGINX installation.  This requires that the AWS account have a registered domain name - see help for aws route53domains list-domains command which can be used to verify existing registered domain names.  Instructions provided at https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating.html can be used to create an alias record for the load balancer. 

It is also possible to perform this by using the following commands.  Ensure that jq is installed on the host if using these commands.

  • Get the value for the ingress' external ip (reference in later commands as <ingress_ext_ip>)

    kubectl -n ingress-nginx get svc ingress-nginx-controller --no-headers |awk '{print $4}'

  • Get the value for the zone id (reference in later commands as  <zone_id>) for the domain the record is to be created under -  substitute for <domain name> when submitting this command  

    aws route53 list-hosted-zones-by-name --dns-name "<domain name>"  --query "HostedZones[].Id" --output text | cut -d/ -f3

  • Get the value for the hosted zone id (reference in later commands as <hosted_zone_id>) defined for the load balancer -  substitute for <AWS_region> and <ingress_ext_ip> when submitting this command  

    aws elbv2 describe-load-balancers --region "<AWS_region>" | jq --arg name "<ingress_ext_ip>" -r '.LoadBalancers | .[] | select(.DNSName=="\($name)") | .CanonicalHostedZoneId'

  • Use the values from above commands to run the aws route53 command to create the alias record - substitute for <zone_id>, <hosted_zone_id> and <ingress_ext_id> using the values derived from the above commands.  For <FQDN> substitute a fully qualified domain name based on the domain name of the AWS account.  For example if the account domain is example.com, perhaps the desired <FQDN>  would be svtdemo.example.com.  This FQDN will be used as the spec.route.host field setting in  the WebSphereLibertyApplication deploy yaml file later in this blog when deploying the DayTrader application.

    aws route53 change-resource-record-sets \
      --hosted-zone-id <zone_id> \
      --change-batch '
      {
        "Comment": "Creating Alias resource record set in Route53",
        "Changes": [{
          "Action"              : "CREATE",
          "ResourceRecordSet"  : {
            "Name": "'<FQDN>'",
            "Type"             : "A",
            "AliasTarget": {
               "HostedZoneId": "'<hosted_zone_id>'",
               "DNSName": "'<ingress_ext_ip>'",
               "EvaluateTargetHealth": false
             }
            }
          }
        ]
      }'
    


Install Cert-Manager in your EKS cluster

To allow the configuration of transport layer security (TLS) in WebSphere Liberty Operator and the NGINX ingress controller (which supports TLS termination), install Cert-manager.  It will generate and manage the TLS certificates needed to secure the environment using, in this case, a ClusterIssuer resource configured to use the  Let's Encrypt certificate authority.   It is also possible to use an Issu


First, run the following command to install cert-manager.  Please see https://cert-manager.io/docs/installation/supported-releases/ for newer supported releases of cert-manager and update the version if desired.   

# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml


Verify the cert-manager installation using the following command and ensure the 3 resulting  pods reach Running status: 

# kubectl get pods -n cert-manager

NAME                                      READY   STATUS    RESTARTS   AGE
cert-manager-99bb69456-46mwb              1/1     Running   0          103s
cert-manager-cainjector-ffb4747bb-b8hfc   1/1     Running   0          103s
cert-manager-webhook-545bd5d7d8-gv8mk     1/1     Running   0          102s


Next, to create the ClusterIssuer resource, run the following command, replacing EMAIL_ADDRESS with your valid email address.  This email address will be included in the certificates and also used by  Let’s Encrypt to send information and alerts regarding the certificates

# cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: EMAIL_ADDRESS
    privateKeySecretRef:
      name: letsencrypt
    solvers:
    - http01:
        ingress:
          class: nginx
          podTemplate:
            spec:
              nodeSelector:
                "kubernetes.io/os": linux
EOF



Run the script and verify the creation of the ClusterIssuer by running the following command:

# kubectl describe clusterissuer letsencrypt

Install the Operator Lifecycle Manager (OLM) in your EKS cluster

WebSphere Liberty Operator (WLO) can be installed with or without Operator Lifecycle Manager (OLM).  Here the Operator SDK is used to install OLM.  This SDK is a framework to make writing operators easier, but it also includes a command to install OLM on Kubernetes clusters.  Follow the instructions at https://sdk.operatorframework.io/docs/installation/ to install the SDK on the local environment.

Then to install OLM to the Kubernetes cluster, run:

# operator-sdk olm install

Alternatively, OLM could have been installed using instructions found for an appropriate release at https://github.com/operator-framework/operator-lifecycle-manager/releases.

Install the WebSphere Liberty Operator

To install the WebSphere Liberty operator, there are two steps:

  • Add IBM Operator Catalog to the cluster 
  • Install the WebSphere Liberty operator by creating a Subscription

Add IBM Operator Catalog to the cluster


Create a file named ibm_catalog_source.yaml with the following content:

 

apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  name: ibm-operator-catalog
  namespace: olm
spec:
  displayName: IBM Operator Catalog
  publisher: IBM
  sourceType: grpc
  image: icr.io/cpopen/ibm-operator-catalog:latest
  grpcPodConfig:
    securityContextConfig: restricted
  updateStrategy:
    registryPoll:
      interval: 45m

Please note that the namespace in the CatalogSource is olm.  This namespace was created during the install of OLM.


Run the following command to add this to the OLM catalog:

# kubectl apply -f ibm_catalog_source.yaml -n olm


Verify the catalog entry:

# kubectl get CatalogSources ibm-operator-catalog -n olm

 

Install the Websphere Liberty Operator by creating a subscription


To install the operator, create a subscription to the WebSphere Liberty Operator in the catalogsource just added.  For this environment, the operator will be installed in AllNamespaces mode.  For information on installing in other modes, refer to Installing the WebSphere Liberty operator without OLM.


To create the subscription, create a file named wlo-sub.yaml with the following content: 

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: websphere-liberty-operator-subscription
  namespace: operators
spec:
  channel:  v1.1
  name: ibm-websphere-liberty
  source: ibm-operator-catalog
  sourceNamespace: olm
  installPlanApproval: Automatic

Notice that the namespace for this subscription is operators.  This namespace was created during the install of OLM and is associated with a “global Operators” group that watches all namespaces.

Run the following command to add this to the OLM catalog:

# kubectl apply -f wlo-sub.yaml 

 

Verify that the operator is installed and PHASE is Succeeded:

# kubectl get csv -n operators

 

Install the Sample Daytrader Application

Now that the WebSphere Liberty Operator is successfully installed, the daytrader7 application can be installed.
There are 3 steps to consider:

  • Build or use existing sample-daytrader7 application image  
  • Create DB2 database for daytrader7 application or use sample DB2 container
  • Deploy the daytrader7 application


If there is a need to build the application image OR use the sample DB2 container, clone the application Git repo for sample-daytrader7 to the local machine.

# git clone https://github.com/WASdev/sample.daytrader7.git

Build or use existing sample-daytrader7 application image

A prebuilt image of the sample-daytrader7 application is available at 'docker.io/dguinan/sample-daytrader7:latest' .

To build the image if desired, complete the following steps: 

  • cd sample.daytrader7 and run 'mvn install' to compile and create application ear file.
  • Build application image sample-daytrader7 with command 'podman build -t sample-daytrader7 -f Containerfile_db2 .'
  • Upload the sample-daytrader7 image to a repo that your cluster can access such as Docker Hub or AWS Elastic Container Registry (ECR).  For example,
    • podman tag sample-daytrader7 docker.io/mydockerid/sample-daytrader7
    • podman push docker.io/mydockerid/sample-daytrader7

Create DB2 for daytrader7 application


If a DB2 database is already available for the application, skip this setup and add that DB2 database information in spec.env of daytrader7-wldemo-deploy.yaml discussed in the next topic.  


If there is no existing database, the cloned repo contains the configuration needed to deploy a sample DB2 container with a database for use with this sample daytrader7 application.  The files and image used to create this container is for demonstration purposes only and is not supported nor recommended for production use.

To deploy this sample database container: 

  • Create a daytrader7 namespace

    # kubectl create namespace daytrader7
  • Deploy sample DB2 container to the cluster, by going to the 'sample.daytrader7/deploy' folder of the Git repo and applying files as follows:

    # kubectl -n daytrader7 apply -f db2-role-n-sa.yaml
    # kubectl -n daytrader7 apply -f db2-secret.yaml
    # kubectl -n daytrader7 apply -f tradedb-service.yaml
    # kubectl -n daytrader7 apply -f tradedb.yaml
  • Verify that the DB2 pod is in the Running state

    # kubectl -n daytrader7 get pods
    NAME                         READY   STATUS    RESTARTS   AGE
    trade-db2-7fb8d89c86-m7lcx   1/1     Running   0          51s
    

Deploy the daytrader7 application

Create a WebSphereLibertyApplication yaml file using the sample daytrader7-wldemo-deploy.yaml file below.  The following fields may require updating:   

Link back to where FQDN was previously created.

  • spec.applicationImage:  location of the daytrader application image that was previously built such as 'docker.io/mydockerid/sample-daytrader7:latest' or prebuilt image 'docker.io/dguinan/sample-daytrader7:latest'
  • spec.route.annotations.cert-manager.io/cluster-issuer:  the Issuer or ClusterIssuer resource name - note that in earlier resource config, metadata.name  was letsencrypt
  • spec.route.host: the full hostname which is the FQDN generated when creating the alias record  


Sample daytrader7-wldemo-deploy.yaml file

apiVersion: liberty.websphere.ibm.com/v1
kind: WebSphereLibertyApplication
metadata:
  name: daytrader7
spec:
  license:
    accept: true
    edition: IBM WebSphere Application Server
    productEntitlementSource: Standalone
    metric: Virtual Processor Core (VPC)
  applicationImage: 'docker.io/dguinan/sample-daytrader7:latest'
  pullPolicy: Always
  replicas: 1
  route:
    annotations:
      kubernetes.io/ingress.class: nginx
      cert-manager.io/cluster-issuer: letsencrypt
      nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
      nginx.ingress.kubernetes.io/affinity: "cookie"
      nginx.ingress.kubernetes.io/session-cookie-name: "route"
      nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
    host: svtdemo.example.com
    certificateSecretRef: tls-secret
    path: /daytrader
    pathType: Prefix   
  expose: true
  service:
    port: 9443
    type: ClusterIP
  probes:
    startup: {}
    liveness: {}
    readiness: {}
  env:
    - name: tradeDbHost
      value: trade-db2
    - name: tradeDbPort
      value: "50000"
    - name: tradeDbName
      value: TRADEDB
    - name: dbUser
      value: db2inst1
    - name: dbPass
      valueFrom:
        secretKeyRef:
          name: db-credential
          key: dbpw
  resources:
    requests:
      cpu: 500m
      memory: 1024Mi
    limits:
      cpu: 500m
      memory: 2048Mi

Note: The WebSphereLibertyApplication custom resource that was created above was fairly basic, but please see WebSphereLibertyApplication custom resource documentation for other configurable parameters. Please note that if deploying an application on EKS that has been configured with the spec.autoscaling parameter, it may be necessary to also install the Kubernetes Metrics Server on your cluster for successful scaling to occur.


Deploy the daytrader7 application:

# kubectl -n daytrader7 apply -f daytrader7-wldemo-deploy.yaml

 

Verify the daytrader7 application is deployed and pods are in running state

# kubectl -n daytrader7 get wlapps
NAME         IMAGE                                        EXPOSED   RECONCILED   RESOURCESREADY   READY   AGE
daytrader7   docker.io/dguinan/sample-daytrader7:latest   true      True         True             True    89s

# kubectl -n daytrader7 get pod NAME READY STATUS RESTARTS AGE daytrader7-6fd857bdb-qqb4v 1/1 Running 0 99s trade-db2-7fb8d89c86-m7lcx 1/1 Running 0 12m

The daytrader application should now be accessible using the Ingress URL and daytrader context root which is /daytrader.  If the results of an ingress query produced the following modified response, access to the application would be https://svtdemo.example.com/daytrader.  

# kubectl -n daytrader7 get ingress
NAME         CLASS    HOSTS                 ADDRESS                            PORTS     AGE
daytrader7   <none>   svtdemo.example.com   abcxxxx-123xxx.elb.amazonaws.com   80, 443   114s

 

0 comments
99 views

Permalink