Model in Image

This sample demonstrates how to use the WebLogic Kubernetes Operator (hereafter “the operator”) to set up a WebLogic Server (WLS) cluster on the Azure Kubernetes Service (AKS) using the model in image domain home source type. After going through the steps, your WLS domain runs on an AKS cluster instance and you can manage your WLS domain by interacting with the operator.

Contents

Prerequisites

This sample assumes the following prerequisite environment.

Prepare parameters

Set required parameters by running the following commands.

# Change these parameters as needed for your own environment
export ORACLE_SSO_EMAIL=<replace with your oracle account email>
export ORACLE_SSO_PASSWORD="<replace with your oracle password.>"

export BASE_DIR=~
export NAME_PREFIX=wls

# Used to generate resource names.
export TIMESTAMP=`date +%s`
export ACR_NAME="acr${TIMESTAMP}"
export AKS_CLUSTER_NAME="aks${TIMESTAMP}"
export AKS_PERS_RESOURCE_GROUP="resourcegroup${TIMESTAMP}"
export AKS_PERS_LOCATION=eastus

export SECRET_NAME_DOCKER="${NAME_PREFIX}regcred"
export WEBLOGIC_USERNAME=weblogic
export WEBLOGIC_PASSWORD=Secret123456
export WEBLOGIC_WDT_PASSWORD=Secret123456

Oracle Container Registry

The following steps will direct you to accept the license agreement for WebLogic Server. Make note of your Oracle Account password and email. This sample pertains to 12.2.1.4, but other versions may work as well.

  • In a web browser, navigate to

    <a href=“ https://container-registry.oracle.com

    target="_blank" rel=“noopener noreferrer”

    https://container-registry.oracle.com and log in using the Oracle Single Sign-On authentication service. If you do not already have SSO credentials, at the top of the page, click the Sign In link to create them.

  • The Oracle Container Registry provides a WebLogic 12.2.1.4 General Availability (GA) installation image that is used in this sample.
    • In the Oracle Container Registry, navigate to Middleware, then weblogic.
    • On the left, choose a language and accept the license agreement. You will then see a message such as: “You last accepted the Oracle Standard Terms and Restrictions on 08/10/2020 at 06:12 AM Coordinated Universal Time (UTC).”
  • NOTE: General Availability (GA) images are suitable for demonstration and development purposes only where the environments are not available from the public Internet; they are not acceptable for production use. In production, you should always use CPU (patched) images from the OCR or create your images using the

    <a href=“ https://oracle.github.io/weblogic-image-tool/userguide/tools/create-image/"

    target="_blank” rel=“noopener noreferrer”

    WebLogic Image Tool

    (WIT) with the –recommendedPatches option. For more guidance, see

    <a href=“ https://www.oracle.com/pls/topic/lookup?ctx=en/middleware/standalone/weblogic-server/14.1.1.0&id=LOCKD-GUID-2DA84185-46BA-4D7A-80D2-9D577A4E8DE2"

    target="_blank” rel=“noopener noreferrer”

    Apply the Latest Patches and Updates

    in Securing a Production Environment for Oracle WebLogic Server.

  • Ensure that Docker is running. Find and pull the WebLogic 12.2.1.4 installation image:
    $ docker login container-registry.oracle.com -u ${ORACLE_SSO_EMAIL} -p ${ORACLE_SSO_PASSWORD}
    $ docker pull container-registry.oracle.com/middleware/weblogic:14.1.2.0-generic-jdk17-ol8

If you have problems accessing the Oracle Container Registry, you can build your own images from the

<a href=“ https://github.com/oracle/docker-images/tree/main/OracleWebLogic/dockerfiles"

target="_blank” rel=“noopener noreferrer”

Oracle GitHub repository .

Sign in with Azure CLI

The steps in this section show you how to sign in to the Azure CLI.

  1. Open a Bash shell.

  2. Sign out and delete some authentication files to remove any lingering credentials.

    $ az logout
    $ rm ~/.azure/accessTokens.json
    $ rm ~/.azure/azureProfile.json
  3. Sign in to your Azure CLI.

    $ az login
  4. Set the subscription ID. Be sure to replace the placeholder with the appropriate value.

    $ export SUBSCRIPTION_ID="<your-sub-id>"
    $ az account set -s $SUBSCRIPTION_ID

Download the WebLogic Kubernetes Operator sample

Download the WebLogic Kubernetes Operator sample ZIP file. We will use several scripts in this zip file to create a WebLogic domain. This sample was tested with v4.2.8, but should work with the latest release.

$ cd $BASE_DIR
$ mkdir sample-scripts
$ curl -m 120 -fL https://github.com/oracle/weblogic-kubernetes-operator/releases/download/v4.2.8/sample-scripts.zip \
      -o ${BASE_DIR}/sample-scripts/sample-scripts.zip
$ unzip ${BASE_DIR}/sample-scripts/sample-scripts.zip -d ${BASE_DIR}/sample-scripts

Create Resource Group

Create the resource group by issuing the following commands.

$ az extension add --name resource-graph
$ az group create --name $AKS_PERS_RESOURCE_GROUP --location $AKS_PERS_LOCATION

Create the AKS cluster

This sample doesn’t enable application routing. If you want to enable application routing, follow

<a href=“ https://learn.microsoft.com/azure/aks/app-routing?tabs=default%2Cdeploy-app-default"

target="_blank” rel=“noopener noreferrer”

Managed nginx Ingress with the application routing add-on in AKS .

Run the following command to create the AKS cluster.

$ az aks create \
   --resource-group $AKS_PERS_RESOURCE_GROUP \
   --name $AKS_CLUSTER_NAME \
   --node-count 2 \
   --generate-ssh-keys \
   --nodepool-name nodepool1 \
   --node-vm-size Standard_DS2_v2 \
   --location $AKS_PERS_LOCATION \
   --enable-managed-identity

Successful output will be a JSON object with the entry "type": "Microsoft.ContainerService/ManagedClusters".

After the deployment finishes, run the following command to connect to the AKS cluster. This command updates your local ~/.kube/config so that subsequent kubectl commands interact with the named AKS cluster.

$ az aks get-credentials --resource-group $AKS_PERS_RESOURCE_GROUP --name $AKS_CLUSTER_NAME

Successful output will look similar to:

Merged "wlsaks1596087429" as current context in /home/username/.kube/config

After your Kubernetes cluster is up and running, run the following commands to make sure kubectl can access the Kubernetes cluster:

$ kubectl get nodes -o wide

Successful output will look like the following.

NAME                                STATUS   ROLES   AGE    VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
aks-nodepool1-15679926-vmss000000   Ready    agent   118s   v1.25.6   10.224.0.4    <none>        Ubuntu 22.04.2 LTS   5.15.0-1041-azure   containerd://1.7.1+azure-1
aks-nodepool1-15679926-vmss000001   Ready    agent   2m8s   v1.25.6   10.224.0.5    <none>        Ubuntu 22.04.2 LTS   5.15.0-1041-azure   containerd://1.7.1+azure-1

NOTE: If you run into VM size failure, see Troubleshooting - Virtual Machine size is not supported .

Install WebLogic Kubernetes Operator

The WebLogic Kubernetes Operator is an adapter to integrate WebLogic Server and Kubernetes, allowing Kubernetes to serve as container infrastructure hosting WLS instances. The operator runs as a Kubernetes Pod and stands ready to perform actions related to running WLS on Kubernetes.

Create a namespace and service account for the operator.

$ kubectl create namespace sample-weblogic-operator-ns

The output will show something similar to the following:

namespace/sample-weblogic-operator-ns created
$ kubectl create serviceaccount -n sample-weblogic-operator-ns sample-weblogic-operator-sa

The output will show something similar to the following:

serviceaccount/sample-weblogic-operator-sa created

Validate the service account was created with this command.

$ kubectl -n sample-weblogic-operator-ns get serviceaccount

The output will show something similar to the following:

NAME                          SECRETS   AGE
default                       1         9m24s
sample-weblogic-operator-sa   1         9m5s

Install the operator. The operator’s Helm chart is located in the kubernetes/charts/weblogic-operator directory. This sample installs the operator using Helm charts from GitHub. It may take you several minutes to install the operator.

$ helm repo add weblogic-operator https://oracle.github.io/weblogic-kubernetes-operator/charts --force-update

Update the repo to get the latest Helm charts. It is a best practice to do this every time before installing a new operator version. In this example, we are using a pinned version, but you may also find success if you use the latest version. In this case, you can omit the --version argument. Be warned that these instructions have only been tested with the exact version shown.

$ helm repo update
$ helm install weblogic-operator weblogic-operator/weblogic-operator \
  --namespace sample-weblogic-operator-ns \
  --version 4.2.8 \
  --set serviceAccount=sample-weblogic-operator-sa \
  --wait

The output will show something similar to the following:

NAME: weblogic-operator
LAST DEPLOYED: Fri Aug 12 14:28:47 2022
NAMESPACE: sample-weblogic-operator-ns
STATUS: deployed
REVISION: 1
TEST SUITE: None
Tip

If you wish to use a more recent version of the operator, replace the 4.2.8 in the preceding command with the other version number. To see the list of versions, visit the GitHub releases page .

Verify the operator with the following commands; the status will be Running.

$ helm list -A

The output will show something similar to the following:

NAME                    NAMESPACE                       REVISION        UPDATED                                 STATUS CHART                    APP VERSION
weblogic-operator       sample-weblogic-operator-ns     1               2023-05-15 10:31:05.1890341 +0800 CST   deployeweblogic-operator-4.2.8  4.2.8
$ kubectl get pods -n sample-weblogic-operator-ns

The output will show something similar to the following:

NAME                                         READY   STATUS    RESTARTS   AGE
weblogic-operator-54b5c8df46-g4rcm           1/1     Running   0          86s
weblogic-operator-webhook-6c5885f69f-pd8qw   1/1     Running   0          86s
Note

You can specify the operator image by changing value of --set image. If you run into failures, see Troubleshooting - WebLogic Kubernetes Operator installation failure .

Info

If you have an image built with domain models following Model in Image , you can go to Create WebLogic domain directly.

Create Docker image

Image creation prerequisites

  • The JAVA_HOME environment variable must be set and must reference a valid JDK 8 or 11 installation.

  • Copy the sample to a new directory; for example, use the directory /tmp/mii-sample. In the directory name, mii is short for “model in image”. Model in image is one of three domain home source types supported by the operator. To learn more, see Choose a domain home source type .

    $ rm /tmp/mii-sample -f -r
    $ mkdir /tmp/mii-sample
    $ cp -r $BASE_DIR/sample-scripts/create-weblogic-domain/wdt-artifacts/* /tmp/mii-sample

    Save the model file directory.

    $ export WDT_MODEL_FILES_PATH=/tmp/mii-sample/wdt-model-files

    NOTE: We will refer to this working copy of the sample as /tmp/mii-sample; however, you can use a different location.

  • Download the latest WebLogic Deploying Tooling (WDT) and WebLogic Image Tool (WIT) installer ZIP files to your ${WDT_MODEL_FILES_PATH} directory. Both WDT and WIT are required to create your Model in Image images.

    $ curl -m 120 -fL https://github.com/oracle/weblogic-deploy-tooling/releases/latest/download/weblogic-deploy.zip \
     -o ${WDT_MODEL_FILES_PATH}/weblogic-deploy.zip
    $ curl -m 120 -fL https://github.com/oracle/weblogic-image-tool/releases/latest/download/imagetool.zip \
      -o ${WDT_MODEL_FILES_PATH}/imagetool.zip
  • Set up the WebLogic Image Tool, run the following commands:

    $ unzip ${WDT_MODEL_FILES_PATH}/imagetool.zip -d ${WDT_MODEL_FILES_PATH}
    $ ${WDT_MODEL_FILES_PATH}/imagetool/bin/imagetool.sh cache deleteEntry --key wdt_latest
    $ ${WDT_MODEL_FILES_PATH}/imagetool/bin/imagetool.sh cache addInstaller \
      --type wdt \
      --version latest \
      --path ${WDT_MODEL_FILES_PATH}/weblogic-deploy.zip

    These steps will install WIT to the ${WDT_MODEL_FILES_PATH}/imagetool directory, plus put a wdt_latest entry in the tool’s cache which points to the WDT ZIP file installer. You will use WIT later in the sample for creating model images.

Image creation - Introduction

The goal of image creation is to demonstrate using the WebLogic Image Tool to create an image tagged as wdt-domain-image:WLS-v1 from files that you will stage to ${WDT_MODEL_FILES_PATH}/WLS-v1/.

  • The directory where the WebLogic Deploy Tooling software is installed (also known as WDT Home) is expected in an image’s /auxiliary/weblogic-deploy directory.
  • WDT model YAML (model), WDT variable (property), and WDT archive ZIP (archive) files are expected in directory /auxiliary/models.

Understanding your first archive

See Understanding your first archive .

Staging a ZIP file of the archive

When you create the image, you will use the files in the staging directory, ${WDT_MODEL_FILES_PATH}/WLS-v1. In preparation, you need it to contain a ZIP file of the WDT application archive.

Run the following commands to create your application archive ZIP file and put it in the expected directory:

# Delete existing archive.zip in case we have an old leftover version
$ rm -f ${WDT_MODEL_FILES_PATH}/WLS-v1/archive.zip

Create a ZIP file of the archive in the location that we will use when we run the WebLogic Image Tool.

$ cd /tmp/mii-sample/archives/archive-v1
$ zip -r ${WDT_MODEL_FILES_PATH}/WLS-v1/archive.zip wlsdeploy

Staging model files

In this step, you explore the staged WDT model YAML file and properties in the ${WDT_MODEL_FILES_PATH}/WLS-v1 directory. The model in this directory references the web application in your archive, configures a WebLogic Server Administration Server, and configures a WebLogic cluster. It consists of only two files, model.10.properties, a file with a single property, and, model.10.yaml, a YAML file with your WebLogic configuration.

Here is the WLS model.10.properties:

CLUSTER_SIZE=5

Here is the WLS model.10.yaml:

domainInfo:
    AdminUserName: '@@SECRET:__weblogic-credentials__:username@@'
    AdminPassword: '@@SECRET:__weblogic-credentials__:password@@'
    ServerStartMode: 'prod'

topology:
    Name: '@@ENV:CUSTOM_DOMAIN_NAME@@'
    AdminServerName: 'admin-server'
    Cluster:
        'cluster-1':
            DynamicServers:
                ServerTemplate:  'cluster-1-template'
                ServerNamePrefix: 'managed-server'
                DynamicClusterSize: '@@PROP:CLUSTER_SIZE@@'
                MaxDynamicClusterSize: '@@PROP:CLUSTER_SIZE@@'
                MinDynamicClusterSize: '0'
                CalculatedListenPorts: false
    Server:
        'admin-server':
            ListenPort: 7001
    ServerTemplate:
        'cluster-1-template':
            Cluster: 'cluster-1'
            ListenPort: 8001

appDeployments:
    Application:
        myapp:
            SourcePath: 'wlsdeploy/applications/myapp-v1'
            ModuleType: ear
            Target: 'cluster-1'

The model file:

  • Defines a WebLogic domain with:

    • Cluster cluster-1
    • Administration Server admin-server
    • An EAR application, targeted to cluster-1, located in the WDT archive ZIP file at wlsdeploy/applications/myapp-v1
  • Leverages macros to inject external values:

    • The property file CLUSTER_SIZE property is referenced in the model YAML file DynamicClusterSize and MaxDynamicClusterSize fields using a PROP macro.
    • The model file domain name is injected using a custom environment variable named CUSTOM_DOMAIN_NAME using an ENV macro.
      • You set this environment variable later in this sample using an env field in its Domain.
      • This conveniently provides a simple way to deploy multiple differently named domains using the same model image.
    • The model file administrator user name and password are set using a weblogic-credentials secret macro reference to the WebLogic credential secret.
      • This secret is in turn referenced using the webLogicCredentialsSecret field in the Domain.
      • The weblogic-credentials is a reserved name that always dereferences to the owning Domain actual WebLogic credentials secret name.

A Model in Image image can contain multiple properties files, archive ZIP files, and YAML files but in this sample you use just one of each. For a complete description of Model in Images model file naming conventions, file loading order, and macro syntax, see Model files in the Model in Image user documentation.

Creating the image with WIT

At this point, you have all of the files needed for image wdt-domain-image:WLS-v1 staged; they include:

  • /tmp/sample/wdt-artifacts/wdt-model-files/WLS-v1/model.10.yaml
  • /tmp/sample/wdt-artifacts/wdt-model-files/WLS-v1/model.10.properties
  • /tmp/sample/wdt-artifacts/wdt-model-files/WLS-v1/archive.zip

Now, you use the Image Tool to create an image named wdt-domain-image:WLS-v1. You’ve already set up this tool during the prerequisite steps.

Run the following command to create the image and verify that it worked.

$ ${WDT_MODEL_FILES_PATH}/imagetool/bin/imagetool.sh createAuxImage \
  --tag wdt-domain-image:WLS-v1 \
  --wdtModel ${WDT_MODEL_FILES_PATH}/WLS-v1/model.10.yaml \
  --wdtVariables ${WDT_MODEL_FILES_PATH}/WLS-v1/model.10.properties \
  --wdtArchive ${WDT_MODEL_FILES_PATH}/WLS-v1/archive.zip

This command runs the WebLogic Image Tool to create the domain creation image and does the following:

  • Builds the final container image as a layer on a small busybox base image.
  • Copies the WDT ZIP file that’s referenced in the WIT cache into the image.
    • Note that you cached WDT in WIT using the keyword latest when you set up the cache during the sample prerequisites steps.
    • This lets WIT implicitly assume it’s the desired WDT version and removes the need to pass a -wdtVersion flag.
  • Copies the specified WDT model, properties, and application archives to image location /auxiliary/models.

When the command succeeds, it should end with output like the following:

[INFO   ] Build successful. Build time=70s. Image tag=wdt-domain-image:WLS-v1

Verify the image is available in the local Docker server with the following command.

$ docker images | grep WLS-v1

The output will show something similar to the following:

wdt-domain-image          WLS-v1   012d3bfa3536   5 days ago      1.13GB
Note

The imagetool.sh is not supported on macOS with Apple Silicon. See Troubleshooting - exec format error .

Note

You may run into a Dockerfile parsing error if your Docker buildkit is enabled, see Troubleshooting - WebLogic Image Tool failure .

Pushing the image to Azure Container Registry

AKS can pull images from any container registry, but the easiest integration is to use Azure Container Registry (ACR). In addition to simplicity, using ACR simplifies high availability and disaster recovery with features such as geo-replication. For more information, see

<a href=“ https://learn.microsoft.com/en-us/azure/container-registry/container-registry-geo-replication"

target="_blank” rel=“noopener noreferrer”

Geo-replication in Azure Container Registry . In this section, we will create a new Azure Container Registry, connect it to our pre-existing AKS cluster and push the image built in the preceding section to it. For complete details, see

<a href=“ https://learn.microsoft.com/en-us/azure/container-registry/"

target="_blank” rel=“noopener noreferrer”

Azure Container Registry documentation .

Let’s create an instance of ACR in the same resource group we used for AKS. We will use the environment variables used during the steps above. For simplicity, we use the resource group name as the name of the ACR instance.

$ az acr create --resource-group $AKS_PERS_RESOURCE_GROUP --name $ACR_NAME --sku Basic --admin-enabled true

Closely examine the JSON output from this command. Save the value of the loginServer property aside. It will look something like the following.

"loginServer": "contosoresourcegroup1610068510.azurecr.io",

Use this value to sign in to the ACR instance. Note that because you are signing in with the az CLI, you do not need a password because your identity is already conveyed by having done az login previously.

$ export LOGIN_SERVER=$(az acr show -n $ACR_NAME --resource-group $AKS_PERS_RESOURCE_GROUP --query "loginServer" -o tsv)
$ az acr login --name $LOGIN_SERVER

Successful output will include Login Succeeded.

Ensure Docker is running on your local machine. Run the following commands to tag and push the image to your ACR.

$ docker tag wdt-domain-image:WLS-v1 $LOGIN_SERVER/mii-aks-auxiliary-image:1.0
$ docker push $LOGIN_SERVER/mii-aks-auxiliary-image:1.0

The output will show something similar to the following:

The push refers to repository [contosorgresourcegroup1610068510.azurecr.io/mii-aks-auxiliary-image]
1.0: digest: sha256:208217afe336053e4c524caeea1a415ccc9cc73b206ee58175d0acc5a3eeddd9 size: 2415

Finally, connect the AKS cluster to the ACR. For more details on connecting ACR to an existing AKS, see

<a href=“ https://learn.microsoft.com/en-us/azure/aks/cluster-container-registry-integration?tabs=azure-cli#configure-acr-integration-for-an-existing-aks-cluster"

target="_blank” rel=“noopener noreferrer”

Configure ACR integration for existing AKS clusters .

$ export ACR_ID=$(az acr show -n $ACR_NAME --resource-group $AKS_PERS_RESOURCE_GROUP --query "id" -o tsv)
$ az aks update --name $AKS_CLUSTER_NAME --resource-group $AKS_PERS_RESOURCE_GROUP --attach-acr $ACR_ID

Successful output will be a JSON object with the entry "type": "Microsoft.ContainerService/ManagedClusters".

If you see an error that seems related to you not being an Owner on this subscription, please refer to the troubleshooting section Cannot attach ACR due to not being Owner of subscription .

Create WebLogic domain

In this section, you will deploy the new image to the namespace sample-domain1-ns, including the following steps:

  • Create a namespace for the WebLogic domain.
  • Upgrade the operator to manage the WebLogic domain namespace.
  • Create a secret containing your WebLogic administrator user name and password.
  • Create a secret containing your Model in Image runtime encryption password:
    • All Model in Image domains must supply a runtime encryption Secret with a password value.
    • The runtime encryption password is used to encrypt configuration that is passed around internally by the operator.
    • The value must be kept private but can be arbitrary; you can optionally supply a different secret value every time you restart the domain.
  • Deploy a domain YAML file that references the new image.
  • Wait for the domain’s pods to start and reach their ready state.

Namespace

Create a namespace that can host one or more domains:

$ kubectl create namespace sample-domain1-ns

Label the domain namespace so that the operator can autodetect and create WebLogic Server pods. Without this step, the operator cannot see the namespace.

$ kubectl label namespace sample-domain1-ns weblogic-operator=enabled

Kubernetes Secrets for WebLogic image

You will use the kubernetes/samples/scripts/create-kubernetes-secrets/create-docker-credentials-secret.sh script to create the Docker credentials as a Kubernetes secret to pull image from OCR. Please run:

$ $BASE_DIR/sample-scripts/create-kubernetes-secrets/create-docker-credentials-secret.sh \
  -n sample-domain1-ns \
  -s ${SECRET_NAME_DOCKER} \
  -e ${ORACLE_SSO_EMAIL} \
  -p ${ORACLE_SSO_PASSWORD} \
  -u ${ORACLE_SSO_EMAIL}

The output will show something similar to the following:

secret/wlsregcred created
The secret wlsregcred has been successfully created in the sample-domain1-ns namespace.

Kubernetes Secrets for WebLogic

First, create the secrets needed by the WLS type model domain. For more on secrets in the context of running domains, see Prepare to run a domain . In this case, you have two secrets.

Run the following kubectl commands to deploy the required secrets:

$ kubectl -n sample-domain1-ns create secret generic \
  sample-domain1-weblogic-credentials \
   --from-literal=username="${WEBLOGIC_USERNAME}" \
   --from-literal=password="${WEBLOGIC_PASSWORD}"
$ kubectl -n sample-domain1-ns label  secret \
  sample-domain1-weblogic-credentials \
  weblogic.domainUID=sample-domain1
$ kubectl -n sample-domain1-ns create secret generic \
  sample-domain1-runtime-encryption-secret \
   --from-literal=password="${WEBLOGIC_WDT_PASSWORD}"
$ kubectl -n sample-domain1-ns label  secret \
  sample-domain1-runtime-encryption-secret \
  weblogic.domainUID=sample-domain1

Some important details about these secrets:

  • Make sure to enclose your values in double quotes and perform the necessary escaping to prevent the shell from modifying the values before the secret values are set.

  • Choosing passwords and user names:

    • Set the variables WEBLOGIC_USERNAME and WEBLOGIC_PASSWORD with a user name and password of your choice. The password should be at least eight characters long and include at least one digit. Remember what you specified. These credentials may be needed again later.
    • Set the variable WEBLOGIC_WDT_PASSWORD with a password of your choice.
  • The WebLogic credentials secret:

    • It is required and must contain username and password fields.
    • It must be referenced by the spec.webLogicCredentialsSecret field in your Domain resource YAML file. For complete details about the Domain resource, see the Domain resource reference .
    • It also must be referenced by macros in the domainInfo.AdminUserName and domainInfo.AdminPassWord fields in your model.10.yaml file.
  • The Model WDT runtime encryption secret:

    • This is a special secret required by Model in Image.
    • It must contain a password field.
    • It must be referenced using the spec.model.runtimeEncryptionSecret field in your Domain resource YAML file.
    • It must remain the same for as long as the domain is deployed to Kubernetes but can be changed between deployments.
    • It is used to encrypt data as it’s internally passed using log files from the domain’s introspector job and on to its WebLogic Server pods.
  • Deleting and recreating the secrets:

    • You must delete a secret before creating it, otherwise the create command will fail if the secret already exists.
    • This allows you to change the secret when using the kubectl create secret command.
  • You name and label secrets using their associated domainUID for two reasons:

    • To make it obvious which secrets belong to which domains.
    • To make it easier to clean up a domain. Typical cleanup scripts use the weblogic.domainUID label as a convenience for finding all resources associated with a domain.

Now, you can verify the secrets with command:

kubectl get secrets -n sample-domain1-ns

The output looks similar to the following content.

NAME                                       TYPE                             DATA   AGE
sample-domain1-runtime-encryption-secret   Opaque                           1      19s
sample-domain1-weblogic-credentials        Opaque                           2      28s
wlsregcred                                 kubernetes.io/dockerconfigjson   1      47s

Domain resource

Now, you create a domain YAML file. Think of the domain YAML file as the way to configure some aspects of your WebLogic domain using Kubernetes. The operator uses the Kubernetes “custom resource” feature to define a Kubernetes resource type called Domain. For more on the Domain Kubernetes resource, see Domain Resource . For more on custom resources see the Kubernetes documentation .

We provide a script at $BASE_DIR/sample-scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks-mii-generate-yaml.sh to generate a domain resource description.

Run the following command to generate resource files.

export Domain_Creation_Image_tag="$LOGIN_SERVER/mii-aks-auxiliary-image:1.0"
$ cd $BASE_DIR
$ bash $BASE_DIR/sample-scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks-mii-generate-yaml.sh

After running above commands, you will get three files: mii-initial.yaml, admin-lb.yaml and cluster-lb.yaml.

Run the following command to create the domain custom resource:

$ kubectl apply -f mii-initial.yaml

Successful output will look like:

domain.weblogic.oracle/sample-domain1 created
cluster.weblogic.oracle/sample-domain1-cluster-1 created

Verify the WebLogic Server pods are all running:

$ kubectl get pods -n sample-domain1-ns --watch

Output will look similar to the following.

NAME                                READY   STATUS              RESTARTS   AGE
sample-domain1-introspector-xwpbn   0/1     ContainerCreating   0          0s
sample-domain1-introspector-xwpbn   1/1     Running             0          1s
sample-domain1-introspector-xwpbn   0/1     Completed           0          66s
sample-domain1-introspector-xwpbn   0/1     Terminating         0          67s
sample-domain1-introspector-xwpbn   0/1     Terminating         0          67s
sample-domain1-admin-server         0/1     Pending             0          0s
sample-domain1-admin-server         0/1     Pending             0          0s
sample-domain1-admin-server         0/1     ContainerCreating   0          0s
sample-domain1-admin-server         0/1     Running             0          2s
sample-domain1-admin-server         1/1     Running             0          42s
sample-domain1-managed-server1      0/1     Pending             0          0s
sample-domain1-managed-server1      0/1     Pending             0          0s
sample-domain1-managed-server1      0/1     ContainerCreating   0          0s
sample-domain1-managed-server2      0/1     Pending             0          0s
sample-domain1-managed-server2      0/1     Pending             0          0s
sample-domain1-managed-server2      0/1     ContainerCreating   0          0s
sample-domain1-managed-server2      0/1     Running             0          3s
sample-domain1-managed-server2      1/1     Running             0          40s
sample-domain1-managed-server1      0/1     Running             0          53s
sample-domain1-managed-server1      1/1     Running             0          93s

When the system stabilizes with the following state, it is safe to proceed.

NAME                             READY   STATUS    RESTARTS   AGE
sample-domain1-admin-server      1/1     Running   0          2m
sample-domain1-managed-server1   1/1     Running   0          83s
sample-domain1-managed-server2   1/1     Running   0          83s

It may take you up to 10 minutes to deploy all pods, please wait and make sure everything is ready.

If the system does not reach this state, troubleshoot and resolve the problem before continuing. See Troubleshooting for hints.

Invoke the web application

Create Azure load balancer

Create an Azure public standard load balancer to access the WebLogic Server Administration Console and applications deployed to the cluster.

Use the file admin-lb.yaml to create a load balancer service for the Administration Server. If you are choosing not to use the predefined YAML file and instead created a new one with customized values, then substitute the following content with your domain values.

Click here to view YAML content.
apiVersion: v1
kind: Service
metadata:
  name: sample-domain1-admin-server-external-lb
  namespace: sample-domain1-ns
spec:
  ports:
  - name: default
    port: 7001
    protocol: TCP
    targetPort: 7001
  selector:
    weblogic.domainUID: sample-domain1
    weblogic.serverName: admin-server
  sessionAffinity: None
  type: LoadBalancer

Use the file cluster-lb.yaml to create a load balancer service for the managed servers. If you are choosing not to use the predefined YAML file and instead created new one with customized values, then substitute the following content with your domain values.

Click here to view YAML content.
apiVersion: v1
kind: Service
metadata:
  name: sample-domain1-cluster-1-lb
  namespace: sample-domain1-ns
spec:
  ports:
  - name: default
    port: 8001
    protocol: TCP
    targetPort: 8001
  selector:
    weblogic.domainUID: sample-domain1
    weblogic.clusterName: cluster-1
  sessionAffinity: None
  type: LoadBalancer

Create the load balancer services using the following commands:

$ kubectl apply -f admin-lb.yaml

Successful output will look like:

service/sample-domain1-admin-server-external-lb created
$ kubectl  apply -f cluster-lb.yaml

Successful output will look like:

service/sample-domain1-cluster-1-external-lb created

Get the external IP addresses of the Administration Server and cluster load balancers (please wait for the external IP addresses to be assigned):

$ kubectl get svc -n sample-domain1-ns --watch

Successful output will look like:

NAME                                      TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)          AGE
sample-domain1-admin-server               ClusterIP      None           <none>           7001/TCP         8m33s
sample-domain1-admin-server-external-lb   LoadBalancer   10.0.184.118   52.191.234.149   7001:30655/TCP   2m30s
sample-domain1-cluster-1-lb               LoadBalancer   10.0.76.7      52.191.235.71    8001:30439/TCP   2m25s
sample-domain1-cluster-cluster-1          ClusterIP      10.0.118.225   <none>           8001/TCP         7m53s
sample-domain1-managed-server1            ClusterIP      None           <none>           8001/TCP         7m53s
sample-domain1-managed-server2            ClusterIP      None           <none>           8001/TCP         7m52s

In the example, the URL to access the Administration Server is: http://52.191.234.149:7001/console. The expected username and password must match the values that you chose during the Kubernetes Secrets for WebLogic step.

IMPORTANT: You must ensure that any Network Security Group rules that govern access to the console allow inbound traffic on port 7001.

If the WLS Administration Console is still not available, use kubectl describe domain to check domain status.

$ kubectl describe domain domain1

Make sure the status of cluster-1 is ServersReady and Available.

Click here to view example domain status.
Name:         sample-domain1
Namespace:    sample-domain1-ns
Labels:       weblogic.domainUID=sample-domain1
Annotations:  <none>
API Version:  weblogic.oracle/v9
Kind:         Domain
Metadata:
  Creation Timestamp:  2020-11-30T05:40:11Z
  Generation:          1
  Resource Version:    9346
  Self Link:           /apis/weblogic.oracle/v9/namespaces/sample-domain1-ns/domains/sample-domain1
  UID:                 9f10a602-714a-46c5-8dcb-815616b587af
Spec:
  Admin Server:
    Server Start State:  RUNNING
  Clusters:
    Cluster Name:  cluster-1
    Replicas:      2
    Server Pod:
      Affinity:
        Pod Anti Affinity:
          Preferred During Scheduling Ignored During Execution:
            Pod Affinity Term:
              Label Selector:
                Match Expressions:
                  Key:       weblogic.clusterName
                  Operator:  In
                  Values:
                    $(CLUSTER_NAME)
              Topology Key:  kubernetes.io/hostname
            Weight:          100
    Server Start State:      RUNNING
  Configuration:
    Model:
      Domain Type:                WLS
      Runtime Encryption Secret:  sample-domain1-runtime-encryption-secret
  Domain Home:                    /u01/domains/sample-domain1
  Domain Home Source Type:        FromModel
  Image:                          docker.io/sleepycat2/wls-on-aks:model-in-image
  Image Pull Policy:              IfNotPresent
  Image Pull Secrets:
    Name:                         regsecret
  Include Server Out In Pod Log:  true
  Replicas:                       1
  Restart Version:                1
  Server Pod:
    Env:
      Name:   CUSTOM_DOMAIN_NAME
      Value:  domain1
      Name:   JAVA_OPTIONS
      Value:  -Dweblogic.StdoutDebugEnabled=false
      Name:   USER_MEM_ARGS
      Value:  -Djava.security.egd=file:/dev/./urandom -Xms256m -Xmx512m
    Resources:
      Requests:
        Cpu:            250m
        Memory:         768Mi
  Server Start Policy:  IfNeeded
  Web Logic Credentials Secret:
    Name:  sample-domain1-weblogic-credentials
Status:
  Clusters:
    Cluster Name:      cluster-1
    Maximum Replicas:  5
    Minimum Replicas:  0
    Ready Replicas:    2
    Replicas:          2
    Replicas Goal:     2
  Conditions:
    Last Transition Time:        2020-11-30T05:45:15.493Z
    Reason:                      ServersReady
    Status:                      True
    Type:                        Available
  Introspect Job Failure Count:  0
  Replicas:                      2
  Servers:
    Desired State:  RUNNING
    Health:
      Activation Time:  2020-11-30T05:44:15.652Z
      Overall Health:   ok
      Subsystems:
        Subsystem Name:  ServerRuntime
        Symptoms:
    Node Name:      aks-pool1model-71528953-vmss000001
    Server Name:    admin-server
    State:          RUNNING
    Cluster Name:   cluster-1
    Desired State:  RUNNING
    Health:
      Activation Time:  2020-11-30T05:44:54.699Z
      Overall Health:   ok
      Subsystems:
        Subsystem Name:  ServerRuntime
        Symptoms:
    Node Name:      aks-pool1model-71528953-vmss000000
    Server Name:    managed-server1
    State:          RUNNING
    Cluster Name:   cluster-1
    Desired State:  RUNNING
    Health:
      Activation Time:  2020-11-30T05:45:07.211Z
      Overall Health:   ok
      Subsystems:
        Subsystem Name:  ServerRuntime
        Symptoms:
    Node Name:      aks-pool1model-71528953-vmss000001
    Server Name:    managed-server2
    State:          RUNNING
    Cluster Name:   cluster-1
    Desired State:  SHUTDOWN
    Server Name:    managed-server3
    Cluster Name:   cluster-1
    Desired State:  SHUTDOWN
    Server Name:    managed-server4
    Cluster Name:   cluster-1
    Desired State:  SHUTDOWN
    Server Name:    managed-server5
  Start Time:       2020-11-30T05:40:11.709Z
Events:             <none>

Access the application

Access the Administration Console using the admin load balancer IP address.

$ ADMIN_SERVER_IP=$(kubectl -n sample-domain1-ns get svc sample-domain1-admin-server-external-lb -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ echo "Administration Console Address: http://${ADMIN_SERVER_IP}:7001/console/"

Access the sample application using the cluster load balancer IP address.

## Access the sample application using the cluster load balancer IP.
$ CLUSTER_IP=$(kubectl -n sample-domain1-ns get svc sample-domain1-cluster-1-lb -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ curl http://${CLUSTER_IP}:8001/myapp_war/index.jsp

Successful output will look like:

<html><body><pre>
*****************************************************************

Hello World! This is version 'v1' of the sample JSP web-app.

Welcome to WebLogic Server 'managed-server1'!

  domain UID  = 'sample-domain1'
  domain name = 'domain1'

Found 1 local cluster runtime:
  Cluster 'cluster-1'

Found min threads constraint runtime named 'SampleMinThreads' with configured count: 1

Found max threads constraint runtime named 'SampleMaxThreads' with configured count: 10

Found 0 local data sources:

*****************************************************************
</pre></body></html>

Rolling updates

Naturally, you will want to deploy newer versions of the EAR application, located in the WDT archive ZIP file at wlsdeploy/applications/myapp-v1. To learn how to do this, follow the steps in Update 3 .

Database connection

For guidance on how to connect a database to your AKS with WebLogic Server application, see Deploy a Java application with WebLogic Server on an Azure Kubernetes Service (AKS) cluster .

Clean up resources

Run the following commands to clean up resources.

$ az group delete --yes --no-wait --name $AKS_PERS_RESOURCE_GROUP

Troubleshooting

For troubleshooting advice, see Troubleshooting .