Kubernetes: Deploy a Java Helidon Application

In this tutorial, you use an Oracle Cloud Infrastructure account to set up a Kubernetes cluster. Then, you deploy a Java Helidon application to your cluster. Key tasks include how to:

  • Set up OpenSSL API encryption keys to access your cluster.
  • Set up an authentication token.
  • Set up a Kubernetes cluster on OCI.
  • Set up OCI CLI to access your cluster.
  • Build a Java Helidon application and Docker Image.
  • Push your image to OCIR.
  • Deploy your Docker application to your cluster.
  • Connect to your application from the internet.
A diagram of the components needed to run a Helidon app on Oracle Cloud Infrastructure Container Engine

For additional information, see:

Before You Begin

To successfully perform this tutorial, you must have the following:

If you have Windows, you can Download Git for Windows and access a Linux environment. Here are some options:

Install or have the following applications:

  • JDK 8+ and set JAVA_HOME in .bashrc
  • Python 3
  • Kubernetes 1.11.9+
  • Apache Maven 3.6+
  • Docker 18.0.6+

1. Gather Required Information

Prepare the information you need from the Oracle Cloud Infrastructure Console.

  1. Check your service limits:
    • Regions: minimum 2

      In the top navigation bar, expand <region>. Example: US East (Ashburn) and US West (Phoenix).

    • Compute instances: minimum 3

      Click your profile avatar. Select Tenancy. Go to Service Limits and expand Compute.

    • Block Volume: minimum 50 GBs

      In the Service Limits section, expand Block Volume.

    • Load Balancer: available

      In the Service Limits section, expand Networking.

  2. Have a compartment for your cluster.
  3. Create an authorization token:
    • In the top navigation bar, click your user avatar.
    • Select your username.
    • Click Auth Tokens.
    • Click Generate Token.
    • Give it a description.
    • Click Generate Token.
    • Copy the token and save it.
    Note

    Make sure you save your token right after you create it. You will not have access to it later.
  4. Find your region identifier and region key from Regions and Availability Domains. Example: us-ashburn-1 and iad for Ashburn.
  5. Collect the following information and copy them into your notepad.
    • Auth Token: <auth-token> from step 3.
    • Region: <region-identifier> from step 4. Example: us-ahburn-1.
    • Region Key: <region-key> from step 4. Example: iad.
    • Tenancy name: <tenancy-name> from your user avatar.
    • Tenancy OCID: <tenancy-ocid> from your user avatar, go to Tenancy:<your-tenancy> and copy OCID.
    • Username: <user-name> from your user avatar.
    • User OCID: <user-ocid> from your user avatar, go to User Settings and copy OCID.

2. Set up OCI Command Line Interface

You can use the OCI Command Line Interface (CLI) to push your application to Registry and then pull and deploy it with Container Engine for Kubernetes. In this step, you install and set up the CLI to run on a MacOS or a Linux environment.

  1. Install virtualenv:

    With a virtual environment, you can manage dependencies for your project. Every project can be in its own virtual environment to host independent groups of Python libraries.

    • Ubuntu:
      sudo apt update
      sudo apt install python3-pip
      sudo apt install python3-venv
    • Red Hat Linux: When you install Python 3 from Red Hat Software Collections, venv, virtualenv, and pip will be installed, so you are ready to install whatever modules you choose.
      sudo yum install rh-python36
      sudo pip3 install virtualenv
    • MacOS: When you install Python 3 for MacOS, pip3 will be installed, so you are ready to install modules with pip3.
      brew install python3
      pip3 install pipenv
    Note

    You may need to type "y" a few times to accept the packages that are installed to the VM.
  2. Install a virtual environment wrapper.

    The virtualenvwrapper is an extension to virtualenv. It provides a set of commands, which makes working with virtual environments much more pleasant. It also places all your virtual environments in one place. The virtualenvwrapper provides tab-completion on environment names.

    sudo pip3 install virtualenvwrapper
  3. Set up your virtual environment wrapper in .bashrc.

    Update the file:

    sudo vi .bashrc

    In the file, append the following text and save the file:

    # set up Python env
    export WORKON_HOME=~/envs
    export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
    export VIRTUALENVWRAPPER_VIRTUALENV_ARGS=' -p /usr/bin/python3 '
    source /usr/local/bin/virtualenvwrapper.sh

    Activate the above commands in the current window.

    source ~/.bashrc
  4. Start a virtual environment.
    mkvirtualenv cli-app
    You should see something like: (cli-app) ubuntu@<ubuntu-instance-name>:~$
  5. Install OCI CLI .
    pip3 install oci-cli
  6. Test the installation:
    oci os ns get

    You should get your namespace if everything is set up correctly.

  7. Set up the OCI CLI config file.
    oci setup config

    Enter basic information: (Get the answers from "Gather Required Information" step.)

    • Location for your config [$HOME/.oci/config]: <take-default>
    • User OCID: <user-ocid>
    • Tenancy OCID: <tenancy-ocid>
    • Region (e.g. us-ashburn-1): <region-identifier>

    Set up your OpenSSL API encryption keys:

    • Generate a new API Signing RSA key pair? [Y/n]: Y
    • Directory for your keys [$HOME/.oci]: <take-default>
    • Name for your key [oci_api_key] <take-default>
    Note

    Your private key is oci_api_key.pem and your public key is oci_api_key_public.pem.
  8. Deactivate the virtual environment:
    deactivate

    The (cli-app) prefix in your environment should not be displayed anymore.

    Note

    • Whenever you want to use the OCI CLI, activate it with: workon cli-app
    • workon deactivates the environment you are currently in, if you change project names. This way, you can quickly switch between environments.
  9. Activate the cli-app environment:
    workon cli-app
  10. Copy the public key.
    In the terminal enter:
    cat $HOME/.oci/oci_api_key_public.pem
  11. Add the public key to your user account.
    • From your user avatar, go to User Settings.
    • Click Add Public Key.
    • Select Paste Public Keys.
    • Paste value from previous step, including the lines with BEGIN PUBLIC KEY and END PUBLIC KEY
    • Click Add.
    You have now set up the Oracle Cloud Infrastructure CLI to connect to your tenancy with your user account.

3. Create your Kubernetes Cluster

Set up the Kubernetes cluster you will deploy your application to. You will use a wizard to set up your first cluster.

  1. From the OCI main menu select Developer Services then Container Clusters.
  2. Click Create Cluster.
  3. Select Quick Create.
  4. Click Launch Workflow.

    The Cluster Creation dialog is displayed.

  5. Fill in the following information:
    • Name: <your-cluster-name>
    • Compartment: <your-compartment-name>
    • Kubernetes Version: <take-default>
    • Visibility Type: <Private>
    • Shape: VM.Standard.E2.1
    • Number of Nodes: 3
    • Add Ons: <none-selected>
  6. Click Next.

    All your choices are displayed. Review them to make sure everything is configurated correctly.

  7. Click Create Cluster.

    The services set up for your cluster are displayed.

  8. Click Close.
  9. Get a cup of coffee. It may take a few minutes for the cluster to be created.
You have successfully created a Kubernetes cluster.

4. Manage your Kubernetes Cluster (Local)

In this section, you include the Kubernetes cluster information in a .kube/config file, so you can access the cluster and manage deployments. To do that, complete the following steps:

  1. From the OCI main menu select Developer Services then Container Clusters.
  2. Click the link to <your-cluster>.

    The information about your cluster is displayed.

  3. Click Access Cluster.
  4. Select Local Access.
  5. Follow the steps provided in the dialog. The steps for local access are reprinted here for your reference.
    Note

    If you are not in your virtual environment, enter: workon cli-app before you run kubectl commands.

    Activate your cli-app environment and test the oci connection.

    oci -v

    Make your .kube directory if it doesn't exist.

    mkdir -p $HOME/.kube

    Create kubeconfig file for your setup. Use the information from Access Your Cluster dialog.

    oci ce cluster create-kubeconfig <copy-data-from-dialog>

    Export the KUBECONFIG environment variable.

    export KUBECONFIG=$HOME/.kube/config
  6. Test your cluster configuration with the following command:

    List clusters:

    kubectl get service

    Note: If you have existing clusters, the new cluster information is merged with your $HOME/.kube/config file.

With your cluster configured, you are now ready to prepare your application for deployment.

5. Create your Local Helidon Application

Next, build your application Docker image so you can deploy the image to Oracle Cloud Infrastructure Registry (OCIR).

To create a Helidon Docker image, perform the following steps:

  1. Run the following Maven Archetype which creates a Maven project template to start with. This project uses the helidon-quickstart-mp example from the Helidon website.
    mvn archetype:generate -DinteractiveMode=false \
        -DarchetypeGroupId=io.helidon.archetypes \
        -DarchetypeArtifactId=helidon-quickstart-mp \
        -DarchetypeVersion=1.4.4 \
        -DgroupId=io.helidon.examples \
        -DartifactId=helidon-quickstart-mp \
        -Dpackage=io.helidon.examples.quickstart.mp

    The Archetype creates a Maven project under the current directory. You should get something like this:

    [INFO] Project created from Archetype in dir: /home/ubuntu/helidon-quickstart-mp
    [INFO] BUILD SUCCESS
    
  2. Change to the helidon-quickstart-mp directory: cd helidon-quickstart-mp
  3. Build and package the app: mvn package
  4. Run and test the app: java -jar target/helidon-quickstart-mp.jar
  5. Test your application either with curl or from a browser:
    • From a new terminal, connect to your Ubuntu VM with your SSH keys, and then in the command line enter:
      curl -X GET http://localhost:8080/greet
    • From a browser, connect to the public IP address assigned to your VM: http://<x.x.x.x>:8080/greet.

    You should see {"message":"Hello World!"} on your VM, or in your browser.

    You may need to precede the docker commands with sudo in the following steps.

  6. Build the Docker image: docker build -t helidon-quickstart-mp .
  7. Run your Docker image: docker run --rm -p 8080:8080 helidon-quickstart-mp:latest
  8. In a new terminal, test the app: curl -X GET http://localhost:8080/greet.

    Your Docker environment is now set up for Oracle Cloud Infrastructure Registry (OCIR).

References:

6. Deploy your Docker Image to OCIR and your Cluster

Next, push your Docker image to OCIR. Then use that Docker image to deploy your application:

Create an OCIR Repository
  1. From the main menu select Developer Services, then Registry.
  2. Click Create Repository.
  3. Create a private repository with your choice of name. Example: <user-name-repo>.
    You are now ready to push your local image to OCIR.
Push your Local Image

Now change to your local machine so you can push your image to OCIR.

  1. Open a terminal window.
  2. Login to OCIR:
    docker login <region-key>.ocir.io

    You are prompted for your login name and password.

    • Username: <tenancy-name>/<user-name>
    • Password: <auth-token>
  3. List your local Docker images.
    docker images

    To push your local image to OCIR, you must first create a reference to it. This reference includes a fully qualified path to the registry.

    The Docker images on your system are displayed. Identify the image you created in the last section: helidon-quickstart-mp

  4. Before you push your local image to OCIR, you must reference it with a new name that includes the path to OCIR. Then you can push the image with the new name to OCIR. Use the Docker tag command to create a shortcut to your image using the new name:
    sudo docker tag <your-local-image> <registry-image>

    The registry image consists of: <region-key>.ocir.io/<tenancy-name>/<image-folder>/<image-name>

    Example: sudo docker tag helidon-quickstart-mp iad.ocir.io/<tenancy-name>/<image-folder>/helidon-quickstart-mp

    Note

    The <image-folder> is a string of your choosing that is used to group your images. For example, a short version of your username is often used. "John Doe" might use: sudo docker tag helidon-quickstart-mp iad.ocir.io/<tenancy-name>/johnd/helidon-quickstart-mp.
  5. Check your Docker images to see if the reference has been created.
    sudo docker images
    Note

    The new image has the same image ID as your local image.
  6. Push the image to OCIR.
    docker push <registry-image>:latest

    Example: docker push iad.ocir.io/<tenancy-name>/<image-folder>/helidon-quickstart-mp:latest

    You should see your image in OCIR after the push command is complete.

Deploy your Image to your Cluster

With your image in OCIR, you can now deploy your application.

  1. First, create a registry secret for your application. This will be used to authenticate your image when it is deployed to your cluster.

    Fill in the information in this template to create your secret with the name ocirsecret.

    
    kubectl create secret docker-registry ocirsecret --docker-server=<region-code>.ocir.io  --docker-username='<tenancy-name>/<user-name>' --docker-password='<auth-token>' --docker-email='<email-address>'

    After executing the command, you should get message similar to: secret/ocirsecret created.

  2. Verify the secret was created. Issue the following command.
    kubectl get secret ocirsecret --output=yaml

    The output includes information about your secret is shown in the yaml format.

  3. Determine the host URL to your registry image using the following template.
    
    <region-code>.ocir.io/<tenancy-name>/<repo-name>/<image-name>:<tag>
  4. Update the app.yaml located in the helidon-quickstart-mp folder on your system.

    Update or add the following parameters:

    • replicas: 3
    • image: <your-image-url>
    • imagePullPolicy: Always
    • protocol: TCP

    Append your secret with proper indentation. The complete code is shown at the end of this step:

    imagePullSecrets:
      - name: ocirsecret

    Append a service section for a load balancer with the name helidon-quickstart-lb, after the final ---. Here is the complete code:

    
    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: helidon-quickstart-mp
    spec:
      replicas: 3
      template:
        metadata:
          labels:
            app: helidon-quickstart-mp
            version: v1
        spec:
          containers:
          - name: helidon-quickstart-mp
            image: <your-image-url>
            imagePullPolicy: Always
            ports:
            - containerPort: 8080
              protocol: TCP
          imagePullSecrets:
            - name: ocirsecret
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: helidon-quickstart-lb
      labels:
        app: helidon-quickstart-mp
    spec:
      type: LoadBalancer
      ports:
      - port: 8080
      selector:
        app: helidon-quickstart-mp      
                        
  5. Deploy your application with the following command:
    kubectl create -f app.yaml
Test your App

Your load balancer may take a few seconds to load after issuing the command.

  1. Check for your load balancer to deploy.
    kubectl get service

    Repeat the command until the load balancer is assigned an external IP address.

  2. Using the IP address for the load balancer connect to your app in a browser, http://x.x.x.x:8080/greet
Congratulations! You installed and deployed a Helidon application to a Kubernetes cluster on Oracle Cloud Infrastructure.

What's Next

You have successfully created a Hello World application, deployed it to a Kubernetes cluster and made it accessible on the internet, using the Helidon MicroProfile service.

To explore more information about development with Oracle products check out these sites: