Model in Image

This sample demonstrates how to use the Oracle WebLogic Server Kubernetes Operator (hereafter “the operator”) to set up a WebLogic Server (WLS) cluster on the Azure Kubernetes Service (AKS) using the model in image approach. 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.

  • Operating System: GNU/Linux, macOS or WSL2 for Windows 10.
  • Git; use git --version to test if git works. This document was tested with version 2.17.1.
  • Azure CLI; use az --version to test if az works. This document was tested with version 2.9.1.
  • Docker for Desktop. This document was tested with Docker version 20.10.2, build 2291f61
  • kubectl; use kubectl version to test if kubectl works. This document was tested with version v1.16.3.
  • Helm, version 3.1 and later; use helm version to check the helm version. This document was tested with version v3.2.4.
  • A Java JDK, Version 8 or 11. Azure recommends Azul Zulu for Azure. Ensure that your JAVA_HOME environment variable is set correctly in the shells in which you run the commands.
  • Ensure that you have the zip/unzip utility installed; use zip/unzip -v to test if zip/unzip works.
Create a Service Principal for AKS

An AKS cluster requires either an Azure Active Directory (AD) service principal or a managed identity to interact with Azure resources.

We will use a service principal to create an AKS cluster. Follow the commands below to create a new service principal.

Please run az login first. Do set the subscription you want to work with. You can get a list of your subscriptions by running az account list.

# Login
$ az login

# Set your working subscription
$ export SUBSCRIPTION_ID=<your-subscription-id>
$ az account set -s $SUBSCRIPTION_ID

Create the new service principal with the following commands:

# Create Service Principal
$ export SP_NAME=myAKSClusterServicePrincipal
$ az ad sp create-for-rbac --skip-assignment --name $SP_NAME

# Copy the output to a file, we will use it later.

If you see an error similar to the following:

Found an existing application instance of "5pn2s201-nq4q-43n1-z942-p9r9571qr3rp". We will patch it
Insufficient privileges to complete the operation.

The problem may be a pre-existing service principal with the same name. Either delete the other service principal or pick a different name.

Successful output will look like the following:

{
  "appId": "r3qnq743-61s9-4758-8163-4qpo87s72s54",
  "displayName": "myAKSClusterServicePrincipal",
  "name": "http://myAKSClusterServicePrincipal",
  "password": "TfhR~uOJ1C1ftD5NS_LzJJj6UOjS2OwXfz",
  "tenant": "82sr215n-0ns5-404e-9161-206r0oqyq999"
}

Grant your service principal with a contributor role to create AKS resources.

# Use the <appId> from the output of the last command
$ export SP_APP_ID=r3qnq743-61s9-4758-8163-4qpo87s72s54
$ az role assignment create --assignee $SP_APP_ID --role Contributor

Successful output will look like the following:

{
  "canDelegate": null,
  "id": "/subscriptions/p7844r91-o11q-4n7s-np6s-996308sopqo9/providers/Microsoft.Authorization/roleAssignments/4oq396os-rs95-4n6s-n3qo-sqqpnpo91035",
  "name": "4oq396os-rs95-4n6s-n3qo-sqqpnpo91035",
  "principalId": "952551r8-n129-4on3-oqo9-231n0s6011n3",
  "principalType": "ServicePrincipal",
  "roleDefinitionId": "/subscriptions/p7844r91-o11q-4n7s-np6s-996308sopqo9/providers/Microsoft.Authorization/roleDefinitions/o24988np-6180-42n0-no88-20s7382qq24p",
  "scope": "/subscriptions/p7844r91-o11q-4n7s-np6s-996308sopqo9",
}
Oracle Container Registry

You will need an Oracle account. 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 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 Server 12.2.1.4.0 Docker image, which already has the necessary patches applied, and the Oracle WebLogic Server 12.2.1.4.0 and 14.1.1.0.0 images, which do not require any patches.
  • Ensure that Docker desktop is running. Find and then pull the WebLogic 12.2.1.4 install image:
    $ docker pull container-registry.oracle.com/middleware/weblogic:12.2.1.4
    

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

Clone WebLogic Server Kubernetes Operator repository

Clone the Oracle WebLogic Server Kubernetes Operator repository to your machine. We will use several scripts in this repository to create a WebLogic domain. This sample was tested with v3.1.1, but should work with the latest release.

$ git clone --branch v3.2.1 https://github.com/oracle/weblogic-kubernetes-operator.git
$ cd weblogic-kubernetes-operator

Create the AKS cluster

This sample requires that you disable the AKS addon http_application_routing by default. If you want to enable http_application_routing, then follow HTTP application routing.

Run the following commands to create the AKS cluster instance.

# Change these parameters as needed for your own environment
# Specify a prefix to name resources, only allow lowercase letters and numbers, between 1 and 7 characters
$ export NAME_PREFIX=wls
# Used to generate resource names.
$ export TIMESTAMP=`date +%s`
$ export AKS_CLUSTER_NAME="${NAME_PREFIX}aks${TIMESTAMP}"
$ export AKS_PERS_RESOURCE_GROUP="${NAME_PREFIX}resourcegroup${TIMESTAMP}"
$ export AKS_PERS_LOCATION=eastus
$ export SP_APP_ID=<appId from the az ad sp create-for-rbac command>
$ export SP_CLIENT_SECRET=<password from the az ad sp create-for-rbac command>

$ az group create --name $AKS_PERS_RESOURCE_GROUP --location $AKS_PERS_LOCATION
$ 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 \
   --service-principal $SP_APP_ID \
   --client-secret $SP_CLIENT_SECRET

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
NAME                                  STATUS   ROLES   AGE     VERSION    INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
aks-pool1haiche-33688868-vmss000000   Ready    agent   4m25s   v1.17.13   10.240.0.4    <none>        Ubuntu 16.04.7 LTS   4.15.0-1098-azure   docker://19.3.12
aks-pool1haiche-33688868-vmss000001   Ready    agent   4m12s   v1.17.13   10.240.0.5    <none>        Ubuntu 16.04.7 LTS   4.15.0-1098-azure   docker://19.3.12

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

Install WebLogic Server Kubernetes Operator

The Oracle WebLogic Server Kubernetes Operator is an adapter to integrate WebLogic Server and Kubernetes, allowing Kubernetes to serve as a 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
namespace/sample-weblogic-operator-ns created
$ kubectl create serviceaccount -n sample-weblogic-operator-ns sample-weblogic-operator-sa
serviceaccount/sample-weblogic-operator-sa created

Validate the service account was created with this command.

$ kubectl -n sample-weblogic-operator-ns get serviceaccount
NAME                          SECRETS   AGE
default                       1         9m24s
sample-weblogic-operator-sa   1         9m5s

Install the operator. Ensure your current directory is weblogic-kubernetes-operator. It may take you several minutes to install the operator.

# cd weblogic-kubernetes-operator
$ helm install weblogic-operator kubernetes/charts/weblogic-operator \
  --namespace sample-weblogic-operator-ns \
  --set image=ghcr.io/oracle/weblogic-kubernetes-operator:3.1.1 \
  --set serviceAccount=sample-weblogic-operator-sa \
  --set "enableClusterRoleBinding=true" \
  --set "domainNamespaceSelectionStrategy=LabelSelector" \
  --set "domainNamespaceLabelSelector=weblogic-operator\=enabled" \
  --wait
NAME: weblogic-operator
LAST DEPLOYED: Tue Nov 17 09:33:58 2020
NAMESPACE: sample-weblogic-operator-ns
STATUS: deployed
REVISION: 1
TEST SUITE: None

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

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

$ helm list -A
NAME                        NAMESPACE                     REVISION   UPDATED                                 STATUS       CHART                   APP VERSION
sample-weblogic-operator    sample-weblogic-operator-ns   1          2020-11-17 09:33:58.584239273 -0700 PDT deployed     weblogic-operator-3.1
$ kubectl get pods -n sample-weblogic-operator-ns
NAME                                 READY   STATUS    RESTARTS   AGE
weblogic-operator-775b668c8f-nwwnn   1/1     Running   0          32s

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

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

Create Docker image

Image creation prerequisites
  1. The JAVA_HOME environment variable must be set and must reference a valid JDK 8 or 11 installation.

  2. Copy the sample to a new directory; for example, use the directory /tmp/mii-sample.

    $ mkdir /tmp/mii-sample
    
    $ cd kubernetes/samples/scripts/create-weblogic-domain/model-in-image
    
    $ cp -r * /tmp/mii-sample
    

    Note: We will refer to this working copy of the sample as /tmp/mii-sample, (mii is short for model in image); however, you can use a different location.

  3. Download the latest WebLogic Deploying Tooling (WDT) and WebLogic Image Tool (WIT) installer ZIP files to your /tmp/mii-sample/model-images directory. Both WDT and WIT are required to create your Model in Image Docker images.

    $ cd /tmp/mii-sample/model-images
    
    $ curl -m 120 -fL https://github.com/oracle/weblogic-deploy-tooling/releases/latest/download/weblogic-deploy.zip \
     -o /tmp/mii-sample/model-images/weblogic-deploy.zip
    
    $ curl -m 120 -fL https://github.com/oracle/weblogic-image-tool/releases/latest/download/imagetool.zip \
     -o /tmp/mii-sample/model-images/imagetool.zip
    

    To set up the WebLogic Image Tool, run the following commands:

    $ cd /tmp/mii-sample/model-images
    
    $ unzip imagetool.zip
    
    $ ./imagetool/bin/imagetool.sh cache addInstaller \
     --type wdt \
     --version latest \
     --path /tmp/mii-sample/model-images/weblogic-deploy.zip
    

    These steps will install WIT to the /tmp/mii-sample/model-images/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 named model-in-image:WLS-v1 from files that you will stage to /tmp/mii-sample/model-images/model-in-image:WLS-v1/. The staged files will contain a web application in a WDT archive, and WDT model configuration for a WebLogic Administration Server called admin-server and a WebLogic cluster called cluster-1.

A “Model in Image” image contains the following elements:

  • A WebLogic Server installation and a WebLogic Deploy Tooling installation in its /u01/wdt/weblogic-deploy directory.
  • If you have WDT model archive files, then the image must also contain these files in its /u01/wdt/models directory.
  • If you have WDT model YAML file and properties files, then they go in in the same /u01/wdt/models directory. If you do not specify a WDT model YAML file in your /u01/wdt/models directory, then the model YAML file must be supplied dynamically using a Kubernetes ConfigMap that is referenced by your Domain spec.model.configMap field.

We provide an example of using a model ConfigMap later in this sample.

The following sections contain the steps for creating the image model-in-image:WLS-v1.

Understanding your first archive

The sample includes a predefined archive directory in /tmp/mii-sample/archives/archive-v1 that you will use to create an archive ZIP file for the image.

The archive top directory, named wlsdeploy, contains a directory named applications, which includes an ‘exploded’ sample JSP web application in the directory, myapp-v1. Three useful aspects to remember about WDT archives are:

  • A model image can contain multiple WDT archives.
  • WDT archives can contain multiple applications, libraries, and other components.
  • WDT archives have a well defined directory structure, which always has wlsdeploy as the top directory.

The application displays important details about the WebLogic Server instance that it’s running on: namely its domain name, cluster name, and server name, as well as the names of any data sources that are targeted to the server.

Staging a ZIP file of the archive

When you create the image, you will use the files in the staging directory, /tmp/mii-sample/model-in-image__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 /tmp/mii-sample/model-images/model-in-image__WLS-v1/archive.zip
# Move to the directory which contains the source files for our archive
$ cd /tmp/mii-sample/archives/archive-v1
# Zip the archive to the location will later use when we run the WebLogic Image Tool
$ zip -r /tmp/mii-sample/model-images/model-in-image__WLS-v1/archive.zip wlsdeploy
Staging model files

In this step, you explore the staged WDT model YAML file and properties in the /tmp/mii-sample/model-in-image__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 discussion of Model in Images model file naming conventions, file loading order, and macro syntax, see Model files files in the Model in Image user documentation.

Creating the image with WIT

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

  • /tmp/mii-sample/model-images/weblogic-deploy.zip
  • /tmp/mii-sample/model-images/model-in-image__WLS-v1/model.10.yaml
  • /tmp/mii-sample/model-images/model-in-image__WLS-v1/model.10.properties
  • /tmp/mii-sample/model-images/model-in-image__WLS-v1/archive.zip

If you don’t see the weblogic-deploy.zip file, then you missed a step in the prerequisites.

Now, you use the Image Tool to create a Docker image named model-in-image:WLS-v1 with a FROM clause that references a base WebLogic image. You’ve already set up this tool during the prerequisite steps.

Run the following commands to create the model image and verify that it worked:

$ cd /tmp/mii-sample/model-images
$ ./imagetool/bin/imagetool.sh update \
  --tag model-in-image:WLS-v1 \
  --fromImage container-registry.oracle.com/middleware/weblogic:12.2.1.4 \
  --wdtModel      ./model-in-image__WLS-v1/model.10.yaml \
  --wdtVariables  ./model-in-image__WLS-v1/model.10.properties \
  --wdtArchive    ./model-in-image__WLS-v1/archive.zip \
  --wdtModelOnly \
  --wdtDomainType WLS \
  --chown oracle:root

If you don’t see the imagetool directory, then you missed a step in the prerequisites.

The preceding command runs the WebLogic Image Tool in its Model in Image mode, and does the following:

  • Builds the final Docker image as a layer on the container-registry.oracle.com/middleware/weblogic:12.2.1.4 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 /u01/wdt/models.

When the command succeeds, you should see output like the following:

[INFO   ] Build successful. Build time=36s. Image tag=model-in-image:WLS-v1

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

$ docker images | grep WLS-v1
model-in-image          WLS-v1   012d3bfa3536   5 days ago      1.13GB

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 Docker images from any container registry, but the easiest integration is to use Azure Container Registry (ACR). In this section, we will create a new Azure Container Registry, connect it to our pre-existing AKS cluster and push the Docker image built in the preceding section to it. For complete details, see 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 $AKS_PERS_RESOURCE_GROUP --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 AKS_PERS_ACR=<you-ACR-loginServer>
$ az acr login --name $AKS_PERS_ACR

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

$ docker tag model-in-image:WLS-v1 $AKS_PERS_ACR/$AKS_PERS_ACR:model-in-image-aks
$ docker push $AKS_PERS_ACR/$AKS_PERS_ACR:model-in-image-aks
The push refers to repository [contosorgresourcegroup1610068510.azurecr.io/contosorgresourcegroup1610068510.azurecr.io]
model-in-image-aks: digest: sha256:208217afe336053e4c524caeea1a415ccc9cc73b206ee58175d0acc5a3eeddd9 size: 2415

Finally, connect AKS to the ACR. For more details on connecting ACR to an existing AKS, see Configure ACR integration for existing AKS clusters.

$ az aks update --name $AKS_CLUSTER_NAME --resource-group $AKS_PERS_RESOURCE_GROUP --attach-acr $AKS_PERS_RESOURCE_GROUP

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.

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

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.
$ kubectl label namespace sample-domain1-ns weblogic-operator=enabled
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 --from-literal=password=welcome1
$ 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=welcome1
$ kubectl -n sample-domain1-ns label  secret \
  sample-domain1-runtime-encryption-secret \
  weblogic.domainUID=sample-domain1

Some important details about these secrets:

  • 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 encrytion 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.
Kubernetes Secrets for Docker

Deploy a corresponding Kubernetes docker secret to the same namespace to access the image during domain creation.

Use kubernetes/samples/scripts/create-kubernetes-secrets/create-docker-credentials-secret.sh to create the secret. Please invoke the script with the -h option to see the available switches and usage.

$ cd weblogic-kubernetes-operator
$ cd kubernetes/samples/scripts/create-kubernetes-secrets
$ ./create-docker-credentials-secret.sh -h

Get the password for the ACR and store it in the Kubernetes secret.

$ az acr credential show --name $AKS_PERS_ACR
The login server endpoint suffix '.azurecr.io' is automatically omitted.
{
  "passwords": [
    {
      "name": "password",
      "value": "f02Ls3jqnNQ0ToXIoyY2g8oJrVk0w5P/"
    },
    {
      "name": "password2",
      "value": "qbZx1bZT7=rha7Ta6Wa0zfCZqoNMNoj1"
    }
  ],
  "username": "contosoresourcegroup1610068510"
}
$ export AKS_PERS_ACR_PASSWORD=<the-password-from-your-output>

Use the create-docker-credentials-secret.sh script to store the ACR credentials as a Kubernetes secret.

# cd kubernetes/samples/scripts/create-kubernetes-secrets
$ export SECRET_NAME_DOCKER="regsecret"
$ ./create-docker-credentials-secret.sh -s ${SECRET_NAME_DOCKER} -e $AKS_PERS_RESOURCE_GROUP -p $AKS_PERS_ACR_PASSWORD -u $AKS_PERS_RESOURCE_GROUP -d $AKS_PERS_ACR -n sample-domain1-ns
secret/regsecret created
The secret regsecret has been successfully created in the sample-domain1-ns namespace.
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 sample file at kubernetes/samples/scripts/create-weblogic-domain/model-in-image/domain-resources/WLS/mii-initial-d1-WLS-v1.yaml, copy it to a file called /tmp/mii-sample/mii-initial.yaml.

$ cd kubernetes/samples/scripts/create-weblogic-domain/model-in-image/domain-resources/WLS
$ cp mii-initial-d1-WLS-v1.yaml /tmp/mii-sample/mii-initial.yaml

Modify the Domain YAML with your values.

Name in YAML file Example value Notes
spec.image $AKS_PERS_ACR/$AKS_PERS_ACR:model-in-image-aks Must be the same as the value to which you pushed the image to by running the command docker push $AKS_PERS_ACR/$AKS_PERS_ACR:model-in-image-aks.
spec.imagePullSecrets.name regsecret Make sure its value is the same value with ${SECRET_NAME_DOCKER}.

Run the following command to create the domain custom resource:

$ kubectl apply -f /tmp/mii-sample/mii-initial.yaml

Successful output will look like:

domain.weblogic.oracle/sample-domain1 created

Verify the WebLogic Server pods are all running:

$ kubectl get pods -n sample-domain1-ns --watch
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

# The success deployment should be:
$ kubectl get all -n sample-domain1-ns
NAME                                 READY   STATUS    RESTARTS   AGE
pod/sample-domain1-admin-server      1/1     Running   0          16m
pod/sample-domain1-managed-server1   1/1     Running   0          15m
pod/sample-domain1-managed-server2   1/1     Running   0          15m

NAME                                       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
service/sample-domain1-admin-server        ClusterIP   None          <none>        7001/TCP   16m
service/sample-domain1-cluster-cluster-1   ClusterIP   10.0.188.60   <none>        8001/TCP   15m
service/sample-domain1-managed-server1     ClusterIP   None          <none>        8001/TCP   15m
service/sample-domain1-managed-server2     ClusterIP   None          <none>        8001/TCP   15m

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

Invoke the web application

Create Azure load balancer

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

Use the configuration file in kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/model-in-image/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 you domain values.

Click here to view YAML content.

Use the configuration file in kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/model-in-image/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 you domain values.

Click here to view YAML content.

Create the load balancer services using the following command:

$ cd kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/model-in-image
$ kubectl apply -f admin-lb.yaml
service/sample-domain1-admin-server-external-lb created
$ kubectl  apply -f cluster-lb.yaml
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
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. IMPORTANT: You must ensure that any Network Security Group rules that govern access to the console allow inbound traffic on port 7001. The default user name for the Administration Console is weblogic and the default password is welcome1. Please change this for production deployments.

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 the example domain status.
Access the application

Access the Administration Console using the admin load balancer IP address, http://52.191.234.149:7001/console

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

## Access the sample application using the cluster load balancer IP (52.191.235.71)
$ curl http://52.191.235.71:8001/myapp_war/index.jsp
<html><body><pre>
*****************************************************************

Hello World! This is version 'v1' of the mii-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 0 local data sources:

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

$ curl http://52.191.235.71:8001/myapp_war/index.jsp
<html><body><pre>
*****************************************************************

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

Welcome to WebLogic Server 'managed-server2'!

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

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

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.

Clean up resources

Run the following commands to clean up resources.

$ az group delete --yes --no-wait --name $AKS_PERS_RESOURCE_GROUP
$ az group delete --yes --no-wait --name "MC_$AKS_PERS_RESOURCE_GROUP"_"$AKS_CLUSTER_NAME"_"$AKS_PERS_LOCATION"
$ az ad sp delete --id $SP_APP_ID

Troubleshooting

For troubleshooting advice, see Troubleshooting.