diff --git a/documentation/3.3/content/samples/azure-kubernetes-service/domain-on-pv.md b/documentation/3.3/content/samples/azure-kubernetes-service/domain-on-pv.md index 327ce3a0f3f..a7c4f738bff 100644 --- a/documentation/3.3/content/samples/azure-kubernetes-service/domain-on-pv.md +++ b/documentation/3.3/content/samples/azure-kubernetes-service/domain-on-pv.md @@ -15,7 +15,7 @@ This sample demonstrates how to use the [WebLogic Kubernetes Operator](/weblogic - [Create WebLogic domain](#create-weblogic-domain) - [Automation](#automation) - [Deploy sample application](#deploy-sample-application) - - [Access WebLogic Server logs](#access-weblogic-server-logs) + - [Validate NFS volume](#validate-nfs-volume) - [Clean up resources](#clean-up-resources) - [Troubleshooting](#troubleshooting) - [Useful links](#useful-links) @@ -26,7 +26,7 @@ This sample demonstrates how to use the [WebLogic Kubernetes Operator](/weblogic ##### Clone WebLogic Kubernetes Operator repository -Clone the [WebLogic Kubernetes Operator repository](https://github.com/oracle/weblogic-kubernetes-operator) 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. +Clone the [WebLogic Kubernetes Operator repository](https://github.com/oracle/weblogic-kubernetes-operator) to your machine. You will use several scripts in this repository to create a WebLogic domain. This sample was tested with v3.3.7, but should work with the latest release. ```shell $ git clone --branch v{{< latestVersion >}} https://github.com/oracle/weblogic-kubernetes-operator.git @@ -52,17 +52,15 @@ Kubernetes Operators use [Helm](https://helm.sh/) to manage Kubernetes applicati $ helm repo add weblogic-operator https://oracle.github.io/weblogic-kubernetes-operator/charts --force-update ``` ```shell -$ helm install weblogic-operator weblogic-operator/weblogic-operator --version "3.1.1" +$ helm install weblogic-operator weblogic-operator/weblogic-operator --version "3.3.7" ``` The output will show something similar to the following: ```shell -$ helm install weblogic-operator weblogic-operator/weblogic-operator --version "3.1.1" -``` -``` +$ helm install weblogic-operator weblogic-operator/weblogic-operator --version "3.3.7" NAME: weblogic-operator -LAST DEPLOYED: Wed Jul 1 23:47:44 2020 +LAST DEPLOYED: Tue Jan 18 17:07:56 2022 NAMESPACE: default STATUS: deployed REVISION: 1 @@ -87,11 +85,11 @@ weblogic-operator-56654bcdb7-qww7f 1/1 Running 0 - [Create secrets](#create-secrets) - [Create WebLogic Domain](#create-weblogic-domain-1) -Now that we have created the AKS cluster, installed the operator, and verified that the operator is ready to go, we can have the operator create a WLS domain. +Now that You have created the AKS cluster, installed the operator, and verified that the operator is ready to go, you can have the operator create a WLS domain. ##### Create secrets -We will use the `kubernetes/samples/scripts/create-weblogic-domain-credentials/create-weblogic-credentials.sh` script to create the domain credentials as a Kubernetes secret. Please run: +You will use the `kubernetes/samples/scripts/create-weblogic-domain-credentials/create-weblogic-credentials.sh` script to create the domain credentials as a Kubernetes secret. Please run: ``` # cd kubernetes/samples/scripts/create-weblogic-domain-credentials @@ -104,8 +102,7 @@ secret/domain1-weblogic-credentials created secret/domain1-weblogic-credentials labeled The secret domain1-weblogic-credentials has been successfully created in the default namespace. ``` - -We will use the `kubernetes/samples/scripts/create-kubernetes-secrets/create-docker-credentials-secret.sh` script to create the Docker credentials as a Kubernetes secret. Please run: +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. Please run: ```shell # Please change imagePullSecretNameSuffix if you change pre-defined value "regcred" before generating the configuration files. @@ -116,7 +113,7 @@ $ export SECRET_NAME_DOCKER="${NAME_PREFIX}regcred" ``` # cd kubernetes/samples/scripts/create-kubernetes-secrets ``` -```sehll +```shell $ ./create-docker-credentials-secret.sh -s ${SECRET_NAME_DOCKER} -e oracleSsoEmail@bar.com -p oracleSsoPassword -u oracleSsoEmail@bar.com ``` ``` @@ -131,7 +128,6 @@ $ kubectl get secret ``` ``` NAME TYPE DATA AGE -wlsazure-secret Opaque 2 17m regcred kubernetes.io/dockerconfigjson 1 2m25s default-token-csdvd kubernetes.io/service-account-token 3 25m domain1-weblogic-credentials Opaque 2 3m42s @@ -142,12 +138,12 @@ weblogic-operator-secrets Opaque **Note**: If the `NAME` column in your output is missing any of the values shown above, please reexamine your execution of the preceding steps in this sample to ensure that you correctly followed all of them. The `default-token-mwdj8` shown above will have a different ending in your output. ##### Create WebLogic Domain -We will use the `kubernetes/samples/scripts/create-weblogic-domain/domain-home-on-pv/create-domain.sh` script to create the WLS domain in the persistent volume we created previously. +You will use the `kubernetes/samples/scripts/create-weblogic-domain/domain-home-on-pv/create-domain.sh` script to create the WLS domain in the persistent volume you created previously. {{% notice note %}} The `create-domain.sh` script and its inputs file are for demonstration purposes _only_; its contents and the domain resource file that it generates for you might change without notice. In production, we strongly recommend that you use the WebLogic Image Tool and WebLogic Deploy Tooling (when applicable), and directly work with domain resource files instead. {{% /notice%}} -We need to set up the domain configuration for the WebLogic domain. +You need to set up the domain configuration for the WebLogic domain. 1. Check if resources are ready. @@ -166,10 +162,8 @@ We need to set up the domain configuration for the WebLogic domain. --file-share ${AKS_PERS_SHARE_NAME} \ --storage-account ${AKS_PERS_STORAGE_ACCOUNT_NAME} \ --domain-uid domain1 \ - --pv-name ${NAME_PREFIX}-azurefile-${TIMESTAMP} \ --pvc-name ${NAME_PREFIX}-azurefile-${TIMESTAMP} \ - --secret-docker ${SECRET_NAME_DOCKER} \ - --secret-storage ${SECRET_NAME_AZURE_FILE} + --secret-docker ${SECRET_NAME_DOCKER} ``` You will see output with `PASS` if all the resources are ready. The following is an example of output: @@ -181,10 +175,8 @@ We need to set up the domain configuration for the WebLogic domain. Azure Kubenetes Service instacne: wlsaks1612795811 Azure storage account: wlsstorage1612795811 Azure file share: wls-weblogic-1612795811 - Kubenetes secret for Azure storage: wlsazure-secret Kubenetes secret for Docker Account: regcred Kubenetes secret for Weblogic domain: domain1-weblogic-credentials - Persistent Volume: wls-azurefile-1612795811 Persistent Volume Claim: wls-azurefile-1612795811 ``` @@ -301,7 +293,7 @@ We need to set up the domain configuration for the WebLogic domain. troubleshoot the reason and resolve it before proceeding to the next step. - {{% notice note %}} This sample creates WebLogic Server pods with reasonable values for memory, CPU, and JVM heap size (as a percentage of memory). You can supply different values. Edit `~/azure/weblogic-on-aks/domain1.yaml` and set the desired values for `serverPodMemoryRequest`, `serverPodMemoryLimit`, `serverPodCpuRequest`, `serverPodCpuLimit` and `javaOptions` before running `./create-domain.sh -i ~/azure/weblogic-on-aks/domain1.yaml -o ~/azure -e -v`. + {{% notice note %}} This sample creates WebLogic Server pods with reasonable values for memory, CPU, and JVM heap size (as a percentage of memory). These settings were determined by running a skeleton WebLogic domain with minimal or no deployed services and applications on potentially limited or heavily shared container environments. For advice about tuning CPU and memory requests and limits for broader use cases or in a production environment, see the [Pod memory and CPU resources](https://oracle.github.io/weblogic-kubernetes-operator/faq/resource-settings/) FAQ. You can supply different values. Edit `~/azure/weblogic-on-aks/domain1.yaml` and set the desired values for `serverPodMemoryRequest`, `serverPodMemoryLimit`, `serverPodCpuRequest`, `serverPodCpuLimit` and `javaOptions` before running `./create-domain.sh -i ~/azure/weblogic-on-aks/domain1.yaml -o ~/azure -e -v`. {{% /notice%}} Here is an excerpt showing reasonable values: @@ -344,7 +336,7 @@ We need to set up the domain configuration for the WebLogic domain. type: LoadBalancer ``` - Use the sample configuration file `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/domain-on-pv/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. + Use the sample configuration file `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/domain-on-pv/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. ```yaml apiVersion: v1 @@ -510,7 +502,7 @@ For input values, you can edit `kubernetes/samples/scripts/create-weblogic-domai | `dockerEmail` | `yourDockerEmail` | Oracle Single Sign-On (SSO) account email, used to pull the WebLogic Server Docker image. | | `dockerPassword` | `yourDockerPassword`| Password for Oracle SSO account, used to pull the WebLogic Server Docker image, in clear text. | | `dockerUserName` | `yourDockerId` | The same value as `dockerEmail`. | -| `namePrefix` | `0730` | Alphanumeric value used as a disambiguation prefix for several Kubernetes resources. | +| `namePrefix` | `wls` | Alphanumeric value used as a disambiguation prefix for several Kubernetes resources. | If you don't want to change the other parameters, you can use the default values. Please make sure no extra whitespaces are added! @@ -528,7 +520,7 @@ $ ./create-domain-on-aks.sh -i my-create-domain-on-aks-inputs.yaml -o ~/azure -e The script will print the Administration Server address after a successful deployment. The default user name for the Administration Console is `weblogic` and the default password is `welcome1`. Please change this for production deployments. To interact with the cluster using `kubectl`, use `az aks get-credentials` as shown in the script output. -{{% notice info %}} You now have created an AKS cluster with `PersistentVolumeClaim` and `PersistentVolume` to contain the WLS domain configuration files. Using those artifacts, you have used the operator to create a WLS domain. +{{% notice info %}} You now have created an AKS cluster with Azure Files NFS share to contain the WLS domain configuration files. Using those artifacts, you have used the operator to create a WLS domain. {{% /notice %}} #### Deploy sample application @@ -574,22 +566,27 @@ In the example, the application address is: `http://52.224.248.40:8001/testwebap The test application will list the server host and server IP on the page. -#### Access WebLogic Server logs +#### Validate NFS volume -The logs are stored in the Azure file share. Follow these steps to access the log: +There are several approaches to validate the NFS volume: -1. Go to the [Azure Portal](https://ms.portal.azure.com). -2. Go to your resource group. -3. Open the storage account. -4. In the "File service" section of the left panel, select File shares. -5. Select the file share name (e.g. weblogic in this example). -6. Select logs. -7. Select domain1. -8. WebLogic Server logs are listed in the folder. +- Use Azure Storage browser. Make sure you have permission to access the NFS server, see [Azure Storage firewalls and virtual networks document](https://docs.microsoft.com/en-us/azure/storage/common/storage-network-security?tabs=azure-portal) +- Mount the same NFS share in an existing virtual machine from Azure. Access files from the mounted path, see [Mount Azure NFS file share to Linux](https://docs.microsoft.com/en-us/azure/storage/files/storage-files-how-to-mount-nfs-shares). -{{%expand "Click here to view the WebLogic Server logs screenshot." %}} -![WebLogic Server Logs](../screenshot-logs.png) -{{% /expand %}} +Use `kubectl exec` to enter the admin server pod to check file system status: + +```shell +kubectl exec -it domain1-admin-server -- df -h +``` + +You will find output like the following, with filesystem `${AKS_PERS_STORAGE_ACCOUNT_NAME}.file.core.windows.net:/${AKS_PERS_STORAGE_ACCOUNT_NAME}/${AKS_PERS_SHARE_NAME}`, size `100G`, and mounted on `/shared`: + +```text +Filesystem Size Used Avail Use% Mounted on +... +wlsstorage1612795811.file.core.windows.net:/wlsstorage1612795811/wls-weblogic-1612795811 100G 76M 100G 1% /shared +... +``` #### Clean up resources diff --git a/documentation/3.3/content/samples/azure-kubernetes-service/includes/create-aks-cluster-storage.txt b/documentation/3.3/content/samples/azure-kubernetes-service/includes/create-aks-cluster-storage.txt index 6aa2f3d350d..afcf83d9fd5 100644 --- a/documentation/3.3/content/samples/azure-kubernetes-service/includes/create-aks-cluster-storage.txt +++ b/documentation/3.3/content/samples/azure-kubernetes-service/includes/create-aks-cluster-storage.txt @@ -1,86 +1,147 @@ -#### Create storage and set up file share +#### Create storage Our usage pattern for the operator involves creating Kubernetes "persistent volumes" to allow the WebLogic Server to persist its configuration and data separately from the Kubernetes Pods that run WebLogic Server workloads. -We will create an external data volume to access and persist data. There are several options for data sharing as described in [Storage options for applications in Azure Kubernetes Service (AKS)](https://docs.microsoft.com/azure/aks/concepts-storage). +You will create an external data volume to access and persist data. There are several options for data sharing as described in [Storage options for applications in Azure Kubernetes Service (AKS)](https://docs.microsoft.com/azure/aks/concepts-storage). -We will use Azure Files as a Kubernetes volume. For details about this full featured cloud storage solution, see the [Azure Files Documentation](https://docs.microsoft.com/azure/aks/azure-files-volume). +You will dynamically create and use a persistent volume with Azure Files NFS share. For details about this full featured cloud storage solution, see the [Azure Files Documentation](https://docs.microsoft.com/azure/aks/azure-files-dynamic-pv). -##### Create an Azure Storage account +##### Create an Azure Storage account and NFS share -Create a storage account using the Azure CLI. Note that the storage account name can contain only lowercase letters and numbers, and must be between 3 and 24 characters in length: +1. Create an Azure Storage Account. -```shell -# Change the value as needed for your own environment -$ export AKS_PERS_STORAGE_ACCOUNT_NAME="${NAME_PREFIX}storage${TIMESTAMP}" - -$ az storage account create \ - -n $AKS_PERS_STORAGE_ACCOUNT_NAME \ - -g $AKS_PERS_RESOURCE_GROUP \ - -l $AKS_PERS_LOCATION \ - --sku Standard_LRS -``` + Create a storage account using the Azure CLI. Make sure the following values are specified: -Successful output will be a JSON object with the entry `"type": "Microsoft.Storage/storageAccounts"`. + | Option name | Value | Notes | + |-------------------|---------------|-------| + | `name` | `$AKS_PERS_STORAGE_ACCOUNT_NAME` | The storage account name can contain only lowercase letters and numbers, and must be between 3 and 24 characters in length. | + | `sku` | `Premium_LRS` | Only `Premium_LRS` and `Premium_ZRS` work for NFS share, see the [Azure Files NFS Share Documentation](https://docs.microsoft.com/azure/storage/files/storage-files-how-to-create-nfs-shares?tabs=azure-portal#applies-to)| + | `https-only` | `false` | You can't mount an NFS file share unless you disable secure transfer. | + | `default-action` | `Deny` | For security, we suggest that you deny access by default and choose to allow access from the AKS cluster network. | -Now we need to create a file share. To create the file share, you need a storage connection string. Run the `show-connection-string` command to get connection string, then create the share with `az storage share create`, as shown here. + ```shell + # Change the value as needed for your own environment + $ export AKS_PERS_STORAGE_ACCOUNT_NAME="${NAME_PREFIX}storage${TIMESTAMP}" -```shell -# Change value as needed for your own environment -$ export AKS_PERS_SHARE_NAME="${NAME_PREFIX}-weblogic-${TIMESTAMP}" -# Get connection string -$ export AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string -n $AKS_PERS_STORAGE_ACCOUNT_NAME -g $AKS_PERS_RESOURCE_GROUP -o tsv) -# Create file share -$ az storage share create -n $AKS_PERS_SHARE_NAME --connection-string $AZURE_STORAGE_CONNECTION_STRING -``` + $ az storage account create \ + --resource-group $AKS_PERS_RESOURCE_GROUP \ + --name $AKS_PERS_STORAGE_ACCOUNT_NAME \ + --location $AKS_PERS_LOCATION \ + --sku Premium_LRS \ + --kind FileStorage \ + --https-only false \ + --default-action Deny + ``` -Successful output will be exactly the following: + Successful output will be a JSON object with the entry `"type": "Microsoft.Storage/storageAccounts"`. -```shell -{ - "created": true -} -``` +2. Create an NFS share. -The operator uses Kubernetes Secrets. We need a storage key for the secret. These commands query the storage account to obtain the key, and then stores the storage account key as a Kubernetes secret. + To create the file share, you must use `NoRootSquash` to allow the operator to change the ownership of the directory in the NFS share. -```shell -$ export STORAGE_KEY=$(az storage account keys list --resource-group $AKS_PERS_RESOURCE_GROUP --account-name $AKS_PERS_STORAGE_ACCOUNT_NAME --query "[0].value" -o tsv) -``` + Otherwise, you will get an error like `chown: changing ownership of '/shared': Operation not permitted`. -Verify the successful output by examining the `STORAGE_KEY` environment variable. It must not be empty. It must be a long ASCII string. + The following command creates an NFS share with 100GiB: -We will use the `kubernetes/samples/scripts/create-kubernetes-secrets/create-azure-storage-credentials-secret.sh` script to create the storage account key as a Kubernetes secret, naming the secret with value `${NAME_PREFIX}azure-secret`. Please run: + ```shell + # Change value as needed for your own environment + $ export AKS_PERS_SHARE_NAME="${NAME_PREFIX}-weblogic-${TIMESTAMP}" + # Create NFS file share + $ az storage share-rm create \ + --resource-group $AKS_PERS_RESOURCE_GROUP \ + --storage-account $AKS_PERS_STORAGE_ACCOUNT_NAME \ + --name ${AKS_PERS_SHARE_NAME} \ + --enabled-protocol NFS \ + --root-squash NoRootSquash \ + --quota 100 + ``` -```shell -# Please change persistentVolumeClaimNameSuffix if you changed pre-defined value "regcred" before generating the configuration files. -$ export SECRET_NAME_AZURE_FILE="${NAME_PREFIX}azure-secret" + The command provisions an NFS file share with NFS 4.1 or above. -#cd kubernetes/samples/scripts/create-kubernetes-secrets -$ ./create-azure-storage-credentials-secret.sh -s $SECRET_NAME_AZURE_FILE -a $AKS_PERS_STORAGE_ACCOUNT_NAME -k $STORAGE_KEY -``` +3. Configure network security. -You will see the following output: + You must configure the network security allowing access from AKS cluster to the storage account. -```text -secret/wlsazure-secret created -The secret wlsazure-secret has been successfully created in the default namespace. -``` + First, you must get the virtual network name and the subnet name of the AKS cluster. + + Run the following commands to get network information: + + ```shell + # get the resource group name of the AKS managed resources + $ aksMCRGName=$(az aks show --name $AKS_CLUSTER_NAME --resource-group $AKS_PERS_RESOURCE_GROUP -o tsv --query "nodeResourceGroup") + $ echo ${aksMCRGName} + + # get network name of AKS cluster + $ aksNetworkName=$(az resource list --resource-group ${aksMCRGName} --resource-type Microsoft.Network/virtualNetworks -o tsv --query '[*].name') + $ echo ${aksNetworkName} + + # get subnet name of AKS agent pool + $ aksSubnetName=$(az network vnet subnet list --resource-group ${aksMCRGName} --vnet-name ${aksNetworkName} -o tsv --query "[*].name") + $ echo ${aksSubnetName} -##### Create PV and PVC + # get subnet id of the AKS agent pool + $ aksSubnetId=$(az network vnet subnet list --resource-group ${aksMCRGName} --vnet-name ${aksNetworkName} -o tsv --query "[*].id") + $ echo ${aksSubnetId} + ``` -This sample uses Kubernetes Persistent Volume Claims (PVC) as storage resource. These features are passed to Kubernetes using YAML files. The script `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh` generates the required configuration files automatically, given an input file containing the parameters. A parameters file is provided at `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks-inputs.yaml`. Copy and customize this file for your needs. + You must enable the service endpoint `Microsoft.Storage` for the subnet using the following command: -To generate YAML files to create PV and PVC in the AKS cluster, the following values must be substituted in your copy of the input file. + ```shell + $ az network vnet subnet update \ + --resource-group $aksMCRGName \ + --name ${aksSubnetName} \ + --vnet-name ${aksNetworkName} \ + --service-endpoints Microsoft.Storage + ``` + + It takes several minutes to enable the service endpoint; successful output will be a JSON object with string like: + + ```text + "serviceEndpoints": [ + { + "locations": [ + "eastus", + "westus" + ], + "provisioningState": "Succeeded", + "service": "Microsoft.Storage" + } + ``` + + Now you must create a network rule to allow access from AKS cluster. + The following command enables access from AKS subnet to the storage account: + + ```shell + $ az storage account network-rule add \ + --resource-group $AKS_PERS_RESOURCE_GROUP \ + --account-name $AKS_PERS_STORAGE_ACCOUNT_NAME \ + --subnet ${aksSubnetId} + ``` + + Successful output will be a JSON object with virtual network rule like: + + ```text + "virtualNetworkRules": [ + { + "action": "Allow", + "state": "Succeeded", + "virtualNetworkResourceId": "${aksSubnetId}" + } + ] + ``` + +##### Create Storage Class and PVC + +This sample will dynamically create and use a persistent volume with Azure Files in AKS. These features are passed to Kubernetes using YAML files. + +The script `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh` generates the required configuration files automatically, given an input file containing the parameters. + +A parameters file is provided at `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks-inputs.yaml`. Copy and customize this file for your needs. + +To generate YAML files to create Storage Class and PVC in the AKS cluster, the following values must be substituted in your copy of the input file. | Name in YAML file | Example value | Notes | |-------------------|---------------|-------| -| `azureServicePrincipalAppId` | `nr086o75-pn59-4782-no5n-nq2op0rsr1q6` | Application ID of your service principal. | -| `azureServicePrincipalClientSecret` | `8693089o-q190-45ps-9319-or36252s3s90` | A client secret of your service principal. | -| `azureServicePrincipalTenantId` | `72s988os-86s1-cafe-babe-2q7pq011qo47` | Tenant (Directory ) ID of your service principal.| -| `dockerEmail` | `yourDockerEmail` | Oracle Single Sign-On (SSO) account email, used to pull the WebLogic Server Docker image. | -| `dockerPassword` | `yourDockerPassword`| Password for Oracle SSO account, used to pull the WebLogic Server Docker image, in clear text. | -| `dockerUserName` | `yourDockerId` | The same value as `dockerEmail`. | | `namePrefix` | `wls` | Alphanumeric value used as a disambiguation prefix for several Kubernetes resources. Make sure the value matches the value of `${NAME_PREFIX}` to keep names in step-by-step commands the same with those in configuration files. | Use the following command to generate configuration files, assuming the output directory is `~/azure`. The script will overwrite any files generated by a previous invocation. @@ -95,115 +156,67 @@ After running the command, all needed configuration files are generated and outp ```shell The following files were generated: - /home/username/azure/weblogic-on-aks/pv.yaml + /home/username/azure/weblogic-on-aks/azure-csi-nfs.yaml /home/username/azure/weblogic-on-aks/pvc.yaml /home/username/azure/weblogic-on-aks/admin-lb.yaml /home/username/azure/weblogic-on-aks/cluster-lb.yaml /home/username/azure/weblogic-on-aks/domain1.yaml - /home/username/azure/weblogic-on-aks/cluster-admin-role.yaml Completed ``` -**Note:** Beyond the required and default configurations generated by the command, you can modify the generated YAML files to further customize your deployment. For further information about customizing your deployment, consult the operator documentation, [AKS documentation](https://docs.microsoft.com/en-us/azure/aks/), and Kubernetes references. +**Note:** Beyond the required and default configurations generated by the command, you can modify the generated YAML files to further customize your deployment. For further information about customizing your deployment, consult the operator documentation, [AKS documentation](https://docs.microsoft.com/azure/aks/), and Kubernetes references. ##### Apply generated configuration files -In order to mount the file share as a persistent volume, we have provided a configuration file `pv.yaml`. You can find it in your output directory. The following content is an example that uses the value `wls-weblogic` as "shareName", `wlsazure-secret` as "secretName", and the persistent volume name is `wls-azurefile`. +In order to define how an Azure file NFS share is created, we have provided a configuration file `azure-csi-nfs.yaml`. You can find it in your output directory. -We will use the storage class `azurefile`. If you want to create a new class, follow this document [Create a storage class](https://docs.microsoft.com/en-us/azure/aks/azure-files-dynamic-pv#create-a-storage-class). For more information, see the page [Storage options for applications in Azure Kubernetes Service (AKS)](https://docs.microsoft.com/en-us/azure/aks/concepts-storage#storage-classes). +The following command displays the YAML content of your current settings. This should be the same with content in `azure-csi-nfs.yaml`; use value `${AKS_PERS_RESOURCE_GROUP}` as "resourceGroup", `${AKS_PERS_STORAGE_ACCOUNT_NAME}` as "storageAccount", +`${AKS_PERS_SHARE_NAME}` as "shareName", and the Storage Class name is `azurefile-csi-nfs`. -```yaml -apiVersion: v1 -kind: PersistentVolume +This sample uses Azure Files Container Storage Interface (CSI) drivers to manage the NFS file share, provisioner is `file.csi.azure.com`, see the [Azure Files CSI drivers documentation](https://docs.microsoft.com/azure/aks/azure-files-csi). + +```shell +cat <}} https://github.com/oracle/weblogic-kubernetes-operator.git @@ -52,17 +52,15 @@ Kubernetes Operators use [Helm](https://helm.sh/) to manage Kubernetes applicati $ helm repo add weblogic-operator https://oracle.github.io/weblogic-kubernetes-operator/charts --force-update ``` ```shell -$ helm install weblogic-operator weblogic-operator/weblogic-operator --version "3.1.1" +$ helm install weblogic-operator weblogic-operator/weblogic-operator ``` The output will show something similar to the following: ```shell -$ helm install weblogic-operator weblogic-operator/weblogic-operator --version "3.1.1" -``` -``` +$ helm install weblogic-operator weblogic-operator/weblogic-operator NAME: weblogic-operator -LAST DEPLOYED: Wed Jul 1 23:47:44 2020 +LAST DEPLOYED: Tue Jan 18 17:07:56 2022 NAMESPACE: default STATUS: deployed REVISION: 1 @@ -87,11 +85,11 @@ weblogic-operator-56654bcdb7-qww7f 1/1 Running 0 - [Create secrets](#create-secrets) - [Create WebLogic Domain](#create-weblogic-domain-1) -Now that we have created the AKS cluster, installed the operator, and verified that the operator is ready to go, we can have the operator create a WLS domain. +Now that you have created the AKS cluster, installed the operator, and verified that the operator is ready to go, you can have the operator create a WLS domain. ##### Create secrets -We will use the `kubernetes/samples/scripts/create-weblogic-domain-credentials/create-weblogic-credentials.sh` script to create the domain credentials as a Kubernetes secret. Please run: +You will use the `kubernetes/samples/scripts/create-weblogic-domain-credentials/create-weblogic-credentials.sh` script to create the domain credentials as a Kubernetes secret. Please run: ``` # cd kubernetes/samples/scripts/create-weblogic-domain-credentials @@ -104,8 +102,7 @@ secret/domain1-weblogic-credentials created secret/domain1-weblogic-credentials labeled The secret domain1-weblogic-credentials has been successfully created in the default namespace. ``` - -We will use the `kubernetes/samples/scripts/create-kubernetes-secrets/create-docker-credentials-secret.sh` script to create the Docker credentials as a Kubernetes secret. Please run: +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. Please run: ```shell # Please change imagePullSecretNameSuffix if you change pre-defined value "regcred" before generating the configuration files. @@ -116,7 +113,7 @@ $ export SECRET_NAME_DOCKER="${NAME_PREFIX}regcred" ``` # cd kubernetes/samples/scripts/create-kubernetes-secrets ``` -```sehll +```shell $ ./create-docker-credentials-secret.sh -s ${SECRET_NAME_DOCKER} -e oracleSsoEmail@bar.com -p oracleSsoPassword -u oracleSsoEmail@bar.com ``` ``` @@ -131,7 +128,6 @@ $ kubectl get secret ``` ``` NAME TYPE DATA AGE -wlsazure-secret Opaque 2 17m regcred kubernetes.io/dockerconfigjson 1 2m25s default-token-csdvd kubernetes.io/service-account-token 3 25m domain1-weblogic-credentials Opaque 2 3m42s @@ -142,12 +138,12 @@ weblogic-operator-secrets Opaque **Note**: If the `NAME` column in your output is missing any of the values shown above, please reexamine your execution of the preceding steps in this sample to ensure that you correctly followed all of them. The `default-token-mwdj8` shown above will have a different ending in your output. ##### Create WebLogic Domain -We will use the `kubernetes/samples/scripts/create-weblogic-domain/domain-home-on-pv/create-domain.sh` script to create the WLS domain in the persistent volume we created previously. +You will use the `kubernetes/samples/scripts/create-weblogic-domain/domain-home-on-pv/create-domain.sh` script to create the WLS domain in the persistent volume you created previously. {{% notice note %}} The `create-domain.sh` script and its inputs file are for demonstration purposes _only_; its contents and the domain resource file that it generates for you might change without notice. In production, we strongly recommend that you use the WebLogic Image Tool and WebLogic Deploy Tooling (when applicable), and directly work with domain resource files instead. {{% /notice%}} -We need to set up the domain configuration for the WebLogic domain. +You need to set up the domain configuration for the WebLogic domain. 1. Check if resources are ready. @@ -166,10 +162,8 @@ We need to set up the domain configuration for the WebLogic domain. --file-share ${AKS_PERS_SHARE_NAME} \ --storage-account ${AKS_PERS_STORAGE_ACCOUNT_NAME} \ --domain-uid domain1 \ - --pv-name ${NAME_PREFIX}-azurefile-${TIMESTAMP} \ --pvc-name ${NAME_PREFIX}-azurefile-${TIMESTAMP} \ - --secret-docker ${SECRET_NAME_DOCKER} \ - --secret-storage ${SECRET_NAME_AZURE_FILE} + --secret-docker ${SECRET_NAME_DOCKER} ``` You will see output with `PASS` if all the resources are ready. The following is an example of output: @@ -181,10 +175,8 @@ We need to set up the domain configuration for the WebLogic domain. Azure Kubenetes Service instacne: wlsaks1612795811 Azure storage account: wlsstorage1612795811 Azure file share: wls-weblogic-1612795811 - Kubenetes secret for Azure storage: wlsazure-secret Kubenetes secret for Docker Account: regcred Kubenetes secret for Weblogic domain: domain1-weblogic-credentials - Persistent Volume: wls-azurefile-1612795811 Persistent Volume Claim: wls-azurefile-1612795811 ``` @@ -301,7 +293,7 @@ We need to set up the domain configuration for the WebLogic domain. troubleshoot the reason and resolve it before proceeding to the next step. - {{% notice note %}} This sample creates WebLogic Server Pods with reasonable values for memory, CPU, and JVM heap size (as a percentage of memory). These settings were determined by running a skeleton WebLogic domain with minimal or no deployed services and applications on potentially limited or heavily shared container environments. For advice about tuning CPU and memory requests and limits for broader use cases or in a production environment, see the [Pod memory and CPU resources](https://oracle.github.io/weblogic-kubernetes-operator/faq/resource-settings/) FAQ. To supply different values, edit `~/azure/weblogic-on-aks/domain1.yaml` and set the desired values for `serverPodMemoryRequest`, `serverPodMemoryLimit`, `serverPodCpuRequest`, `serverPodCpuLimit` and `javaOptions` before running `./create-domain.sh -i ~/azure/weblogic-on-aks/domain1.yaml -o ~/azure -e -v`. + {{% notice note %}} This sample creates WebLogic Server pods with reasonable values for memory, CPU, and JVM heap size (as a percentage of memory). These settings were determined by running a skeleton WebLogic domain with minimal or no deployed services and applications on potentially limited or heavily shared container environments. For advice about tuning CPU and memory requests and limits for broader use cases or in a production environment, see the [Pod memory and CPU resources](https://oracle.github.io/weblogic-kubernetes-operator/faq/resource-settings/) FAQ. You can supply different values. Edit `~/azure/weblogic-on-aks/domain1.yaml` and set the desired values for `serverPodMemoryRequest`, `serverPodMemoryLimit`, `serverPodCpuRequest`, `serverPodCpuLimit` and `javaOptions` before running `./create-domain.sh -i ~/azure/weblogic-on-aks/domain1.yaml -o ~/azure -e -v`. {{% /notice%}} Here is an excerpt showing reasonable values: @@ -344,7 +336,7 @@ We need to set up the domain configuration for the WebLogic domain. type: LoadBalancer ``` - Use the sample configuration file `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/domain-on-pv/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. + Use the sample configuration file `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/domain-on-pv/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. ```yaml apiVersion: v1 @@ -510,7 +502,7 @@ For input values, you can edit `kubernetes/samples/scripts/create-weblogic-domai | `dockerEmail` | `yourDockerEmail` | Oracle Single Sign-On (SSO) account email, used to pull the WebLogic Server Docker image. | | `dockerPassword` | `yourDockerPassword`| Password for Oracle SSO account, used to pull the WebLogic Server Docker image, in clear text. | | `dockerUserName` | `yourDockerId` | The same value as `dockerEmail`. | -| `namePrefix` | `0730` | Alphanumeric value used as a disambiguation prefix for several Kubernetes resources. | +| `namePrefix` | `wls` | Alphanumeric value used as a disambiguation prefix for several Kubernetes resources. | If you don't want to change the other parameters, you can use the default values. Please make sure no extra whitespaces are added! @@ -528,7 +520,7 @@ $ ./create-domain-on-aks.sh -i my-create-domain-on-aks-inputs.yaml -o ~/azure -e The script will print the Administration Server address after a successful deployment. The default user name for the Administration Console is `weblogic` and the default password is `welcome1`. Please change this for production deployments. To interact with the cluster using `kubectl`, use `az aks get-credentials` as shown in the script output. -{{% notice info %}} You now have created an AKS cluster with `PersistentVolumeClaim` and `PersistentVolume` to contain the WLS domain configuration files. Using those artifacts, you have used the operator to create a WLS domain. +{{% notice info %}} You now have created an AKS cluster with Azure Files NFS share to contain the WLS domain configuration files. Using those artifacts, you have used the operator to create a WLS domain. {{% /notice %}} #### Deploy sample application @@ -574,22 +566,27 @@ In the example, the application address is: `http://52.224.248.40:8001/testwebap The test application will list the server host and server IP on the page. -#### Access WebLogic Server logs +#### Validate NFS volume -The logs are stored in the Azure file share. Follow these steps to access the log: +There are several approaches to validate the NFS volume: -1. Go to the [Azure Portal](https://ms.portal.azure.com). -2. Go to your resource group. -3. Open the storage account. -4. In the "File service" section of the left panel, select File shares. -5. Select the file share name (e.g. weblogic in this example). -6. Select logs. -7. Select domain1. -8. WebLogic Server logs are listed in the folder. +- Use Azure Storage browser. Make sure you have permission to access the NFS server, see [Azure Storage firewalls and virtual networks document](https://docs.microsoft.com/en-us/azure/storage/common/storage-network-security?tabs=azure-portal) +- Mount the same NFS share in an existing virtual machine from Azure. Access files from the mounted path, see [Mount Azure NFS file share to Linux](https://docs.microsoft.com/en-us/azure/storage/files/storage-files-how-to-mount-nfs-shares). -{{%expand "Click here to view the WebLogic Server logs screenshot." %}} -![WebLogic Server Logs](../screenshot-logs.png) -{{% /expand %}} +Use `kubectl exec` to enter the admin server pod to check file system status: + +```shell +kubectl exec -it domain1-admin-server -- df -h +``` + +You will find output like the following, with filesystem `${AKS_PERS_STORAGE_ACCOUNT_NAME}.file.core.windows.net:/${AKS_PERS_STORAGE_ACCOUNT_NAME}/${AKS_PERS_SHARE_NAME}`, size `100G`, and mounted on `/shared`: + +```text +Filesystem Size Used Avail Use% Mounted on +... +wlsstorage1612795811.file.core.windows.net:/wlsstorage1612795811/wls-weblogic-1612795811 100G 76M 100G 1% /shared +... +``` #### Clean up resources diff --git a/documentation/staging/content/samples/azure-kubernetes-service/includes/create-aks-cluster-storage.txt b/documentation/staging/content/samples/azure-kubernetes-service/includes/create-aks-cluster-storage.txt index 6aa2f3d350d..00a9e1c0a42 100644 --- a/documentation/staging/content/samples/azure-kubernetes-service/includes/create-aks-cluster-storage.txt +++ b/documentation/staging/content/samples/azure-kubernetes-service/includes/create-aks-cluster-storage.txt @@ -1,86 +1,147 @@ -#### Create storage and set up file share +#### Create storage Our usage pattern for the operator involves creating Kubernetes "persistent volumes" to allow the WebLogic Server to persist its configuration and data separately from the Kubernetes Pods that run WebLogic Server workloads. -We will create an external data volume to access and persist data. There are several options for data sharing as described in [Storage options for applications in Azure Kubernetes Service (AKS)](https://docs.microsoft.com/azure/aks/concepts-storage). +You will create an external data volume to access and persist data. There are several options for data sharing as described in [Storage options for applications in Azure Kubernetes Service (AKS)](https://docs.microsoft.com/azure/aks/concepts-storage). -We will use Azure Files as a Kubernetes volume. For details about this full featured cloud storage solution, see the [Azure Files Documentation](https://docs.microsoft.com/azure/aks/azure-files-volume). +You will dynamically create and use a persistent volume with Azure Files NFS share. For details about this full featured cloud storage solution, see the [Azure Files Documentation](https://docs.microsoft.com/azure/aks/azure-files-dynamic-pv). -##### Create an Azure Storage account +##### Create an Azure Storage account and NFS share -Create a storage account using the Azure CLI. Note that the storage account name can contain only lowercase letters and numbers, and must be between 3 and 24 characters in length: +1. Create an Azure Storage Account. -```shell -# Change the value as needed for your own environment -$ export AKS_PERS_STORAGE_ACCOUNT_NAME="${NAME_PREFIX}storage${TIMESTAMP}" - -$ az storage account create \ - -n $AKS_PERS_STORAGE_ACCOUNT_NAME \ - -g $AKS_PERS_RESOURCE_GROUP \ - -l $AKS_PERS_LOCATION \ - --sku Standard_LRS -``` + Create a storage account using the Azure CLI. Make sure the following values are specified: -Successful output will be a JSON object with the entry `"type": "Microsoft.Storage/storageAccounts"`. + | Option name | Value | Notes | + |-------------------|---------------|-------| + | `name` | `$AKS_PERS_STORAGE_ACCOUNT_NAME` | The storage account name can contain only lowercase letters and numbers, and must be between 3 and 24 characters in length. | + | `sku` | `Premium_LRS` | Only `Premium_LRS` and `Premium_ZRS` work for NFS share, see the [Azure Files NFS Share Documentation](https://docs.microsoft.com/azure/storage/files/storage-files-how-to-create-nfs-shares?tabs=azure-portal#applies-to).| + | `https-only` | `false` | You can't mount an NFS file share unless you disable secure transfer. | + | `default-action` | `Deny` | For security, we suggest that you deny access by default and choose to allow access from the AKS cluster network. | -Now we need to create a file share. To create the file share, you need a storage connection string. Run the `show-connection-string` command to get connection string, then create the share with `az storage share create`, as shown here. + ```shell + # Change the value as needed for your own environment + $ export AKS_PERS_STORAGE_ACCOUNT_NAME="${NAME_PREFIX}storage${TIMESTAMP}" -```shell -# Change value as needed for your own environment -$ export AKS_PERS_SHARE_NAME="${NAME_PREFIX}-weblogic-${TIMESTAMP}" -# Get connection string -$ export AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string -n $AKS_PERS_STORAGE_ACCOUNT_NAME -g $AKS_PERS_RESOURCE_GROUP -o tsv) -# Create file share -$ az storage share create -n $AKS_PERS_SHARE_NAME --connection-string $AZURE_STORAGE_CONNECTION_STRING -``` + $ az storage account create \ + --resource-group $AKS_PERS_RESOURCE_GROUP \ + --name $AKS_PERS_STORAGE_ACCOUNT_NAME \ + --location $AKS_PERS_LOCATION \ + --sku Premium_LRS \ + --kind FileStorage \ + --https-only false \ + --default-action Deny + ``` -Successful output will be exactly the following: + Successful output will be a JSON object with the entry `"type": "Microsoft.Storage/storageAccounts"`. -```shell -{ - "created": true -} -``` +2. Create an NFS share. -The operator uses Kubernetes Secrets. We need a storage key for the secret. These commands query the storage account to obtain the key, and then stores the storage account key as a Kubernetes secret. + To create the file share, you must use `NoRootSquash` to allow the operator to change the ownership of the directory in the NFS share. -```shell -$ export STORAGE_KEY=$(az storage account keys list --resource-group $AKS_PERS_RESOURCE_GROUP --account-name $AKS_PERS_STORAGE_ACCOUNT_NAME --query "[0].value" -o tsv) -``` + Otherwise, you will get an error like `chown: changing ownership of '/shared': Operation not permitted`. -Verify the successful output by examining the `STORAGE_KEY` environment variable. It must not be empty. It must be a long ASCII string. + The following command creates an NFS share with 100GiB: -We will use the `kubernetes/samples/scripts/create-kubernetes-secrets/create-azure-storage-credentials-secret.sh` script to create the storage account key as a Kubernetes secret, naming the secret with value `${NAME_PREFIX}azure-secret`. Please run: + ```shell + # Change value as needed for your own environment + $ export AKS_PERS_SHARE_NAME="${NAME_PREFIX}-weblogic-${TIMESTAMP}" + # Create NFS file share + $ az storage share-rm create \ + --resource-group $AKS_PERS_RESOURCE_GROUP \ + --storage-account $AKS_PERS_STORAGE_ACCOUNT_NAME \ + --name ${AKS_PERS_SHARE_NAME} \ + --enabled-protocol NFS \ + --root-squash NoRootSquash \ + --quota 100 + ``` -```shell -# Please change persistentVolumeClaimNameSuffix if you changed pre-defined value "regcred" before generating the configuration files. -$ export SECRET_NAME_AZURE_FILE="${NAME_PREFIX}azure-secret" + The command provisions an NFS file share with NFS 4.1 or above. -#cd kubernetes/samples/scripts/create-kubernetes-secrets -$ ./create-azure-storage-credentials-secret.sh -s $SECRET_NAME_AZURE_FILE -a $AKS_PERS_STORAGE_ACCOUNT_NAME -k $STORAGE_KEY -``` +3. Configure network security. -You will see the following output: + You must configure the network security allowing access from AKS cluster to the storage account. -```text -secret/wlsazure-secret created -The secret wlsazure-secret has been successfully created in the default namespace. -``` + First, you must get the virtual network name and the subnet name of the AKS cluster. + + Run the following commands to get network information: + + ```shell + # get the resource group name of the AKS managed resources + $ aksMCRGName=$(az aks show --name $AKS_CLUSTER_NAME --resource-group $AKS_PERS_RESOURCE_GROUP -o tsv --query "nodeResourceGroup") + $ echo ${aksMCRGName} + + # get network name of AKS cluster + $ aksNetworkName=$(az resource list --resource-group ${aksMCRGName} --resource-type Microsoft.Network/virtualNetworks -o tsv --query '[*].name') + $ echo ${aksNetworkName} + + # get subnet name of AKS agent pool + $ aksSubnetName=$(az network vnet subnet list --resource-group ${aksMCRGName} --vnet-name ${aksNetworkName} -o tsv --query "[*].name") + $ echo ${aksSubnetName} -##### Create PV and PVC + # get subnet id of the AKS agent pool + $ aksSubnetId=$(az network vnet subnet list --resource-group ${aksMCRGName} --vnet-name ${aksNetworkName} -o tsv --query "[*].id") + $ echo ${aksSubnetId} + ``` -This sample uses Kubernetes Persistent Volume Claims (PVC) as storage resource. These features are passed to Kubernetes using YAML files. The script `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh` generates the required configuration files automatically, given an input file containing the parameters. A parameters file is provided at `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks-inputs.yaml`. Copy and customize this file for your needs. + You must enable the service endpoint `Microsoft.Storage` for the subnet using the following command: -To generate YAML files to create PV and PVC in the AKS cluster, the following values must be substituted in your copy of the input file. + ```shell + $ az network vnet subnet update \ + --resource-group $aksMCRGName \ + --name ${aksSubnetName} \ + --vnet-name ${aksNetworkName} \ + --service-endpoints Microsoft.Storage + ``` + + It takes several minutes to enable the service endpoint; successful output will be a JSON object with string like: + + ```text + "serviceEndpoints": [ + { + "locations": [ + "eastus", + "westus" + ], + "provisioningState": "Succeeded", + "service": "Microsoft.Storage" + } + ``` + + Now you must create a network rule to allow access from AKS cluster. + The following command enables access from AKS subnet to the storage account: + + ```shell + $ az storage account network-rule add \ + --resource-group $AKS_PERS_RESOURCE_GROUP \ + --account-name $AKS_PERS_STORAGE_ACCOUNT_NAME \ + --subnet ${aksSubnetId} + ``` + + Successful output will be a JSON object with virtual network rule like: + + ```text + "virtualNetworkRules": [ + { + "action": "Allow", + "state": "Succeeded", + "virtualNetworkResourceId": "${aksSubnetId}" + } + ] + ``` + +##### Create Storage Class and PVC + +This sample will dynamically create and use a persistent volume with Azure Files in AKS. These features are passed to Kubernetes using YAML files. + +The script `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh` generates the required configuration files automatically, given an input file containing the parameters. + +A parameters file is provided at `kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks-inputs.yaml`. Copy and customize this file for your needs. + +To generate YAML files to create Storage Class and PVC in the AKS cluster, the following values must be substituted in your copy of the input file. | Name in YAML file | Example value | Notes | |-------------------|---------------|-------| -| `azureServicePrincipalAppId` | `nr086o75-pn59-4782-no5n-nq2op0rsr1q6` | Application ID of your service principal. | -| `azureServicePrincipalClientSecret` | `8693089o-q190-45ps-9319-or36252s3s90` | A client secret of your service principal. | -| `azureServicePrincipalTenantId` | `72s988os-86s1-cafe-babe-2q7pq011qo47` | Tenant (Directory ) ID of your service principal.| -| `dockerEmail` | `yourDockerEmail` | Oracle Single Sign-On (SSO) account email, used to pull the WebLogic Server Docker image. | -| `dockerPassword` | `yourDockerPassword`| Password for Oracle SSO account, used to pull the WebLogic Server Docker image, in clear text. | -| `dockerUserName` | `yourDockerId` | The same value as `dockerEmail`. | | `namePrefix` | `wls` | Alphanumeric value used as a disambiguation prefix for several Kubernetes resources. Make sure the value matches the value of `${NAME_PREFIX}` to keep names in step-by-step commands the same with those in configuration files. | Use the following command to generate configuration files, assuming the output directory is `~/azure`. The script will overwrite any files generated by a previous invocation. @@ -95,115 +156,67 @@ After running the command, all needed configuration files are generated and outp ```shell The following files were generated: - /home/username/azure/weblogic-on-aks/pv.yaml + /home/username/azure/weblogic-on-aks/azure-csi-nfs.yaml /home/username/azure/weblogic-on-aks/pvc.yaml /home/username/azure/weblogic-on-aks/admin-lb.yaml /home/username/azure/weblogic-on-aks/cluster-lb.yaml /home/username/azure/weblogic-on-aks/domain1.yaml - /home/username/azure/weblogic-on-aks/cluster-admin-role.yaml Completed ``` -**Note:** Beyond the required and default configurations generated by the command, you can modify the generated YAML files to further customize your deployment. For further information about customizing your deployment, consult the operator documentation, [AKS documentation](https://docs.microsoft.com/en-us/azure/aks/), and Kubernetes references. +**Note:** Beyond the required and default configurations generated by the command, you can modify the generated YAML files to further customize your deployment. For further information about customizing your deployment, consult the operator documentation, [AKS documentation](https://docs.microsoft.com/azure/aks/), and Kubernetes references. ##### Apply generated configuration files -In order to mount the file share as a persistent volume, we have provided a configuration file `pv.yaml`. You can find it in your output directory. The following content is an example that uses the value `wls-weblogic` as "shareName", `wlsazure-secret` as "secretName", and the persistent volume name is `wls-azurefile`. +In order to define how an Azure file NFS share is created, we have provided a configuration file `azure-csi-nfs.yaml`. You can find it in your output directory. -We will use the storage class `azurefile`. If you want to create a new class, follow this document [Create a storage class](https://docs.microsoft.com/en-us/azure/aks/azure-files-dynamic-pv#create-a-storage-class). For more information, see the page [Storage options for applications in Azure Kubernetes Service (AKS)](https://docs.microsoft.com/en-us/azure/aks/concepts-storage#storage-classes). +The following command displays the YAML content of your current settings. This should be the same with content in `azure-csi-nfs.yaml`; use value `${AKS_PERS_RESOURCE_GROUP}` as "resourceGroup", `${AKS_PERS_STORAGE_ACCOUNT_NAME}` as "storageAccount", +`${AKS_PERS_SHARE_NAME}` as "shareName", and the Storage Class name is `azurefile-csi-nfs`. -```yaml -apiVersion: v1 -kind: PersistentVolume +This sample uses Azure Files Container Storage Interface (CSI) drivers to manage the NFS file share, provisioner is `file.csi.azure.com`, see the [Azure Files CSI drivers documentation](https://docs.microsoft.com/azure/aks/azure-files-csi). + +```shell +cat <, used to create file share, and mount file share. -azureStorageShareNameSuffix: weblogic - #Java Option for WebLogic Server javaOptions: -Dweblogic.StdoutDebugEnabled=false -XX:MinRAMPercentage=25.0 -XX:MaxRAMPercentage=50.0 @@ -72,6 +61,12 @@ javaOptions: -Dweblogic.StdoutDebugEnabled=false -XX:MinRAMPercentage=25.0 -XX:M # Parameter "imagePullSecretName" will be overwritten with this field in kubernetes/samples/scripts/create-weblogic-domain/domain-home-on-pv/create-domain-inputs.yaml imagePullSecretNameSuffix: regcred +# Storage class name for Azure Files using Container Storage Interface driver, see https://docs.microsoft.com/en-us/azure/aks/azure-files-csi#nfs-file-shares +azureFileCsiNfsClassName: azurefile-csi-nfs + +# The suffix of azure storage file share name, the complete value is ${namePrefix}-${azureStorageShareNameSuffix}-, used to create file share, and mount file share. +azureStorageShareNameSuffix: weblogic + # Resource request for each server pod (Memory and CPU). This is minimum amount of compute # resources required for each server pod. Edit value(s) below as per pod sizing requirements. # These are optional diff --git a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh index 3f9f169de37..e81e38b4181 100755 --- a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh +++ b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/create-domain-on-aks.sh @@ -3,10 +3,10 @@ # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # # Description -# This sample script creates a WebLogic Server domain home on the Azure Kubernetes Service (AKS). -# It creates a new Azure resource group, with a new Azure Storage Account and Azure File Share to allow WebLogic +# This sample script creates a WebLogic Server domain home on the Azure Kubernetes Service (AKS). +# It creates a new Azure resource group, with a new Azure Storage Account and Azure File Share to allow WebLogic # to persist its configuration and data separately from the Kubernetes pods that run WebLogic workloads. -# Besides, it also generates the domain resource yaml files, which can be used to restart the Kubernetes +# Besides, it also generates the domain resource yaml files, which can be used to restart the Kubernetes # artifacts of the corresponding domain. # # The Azure resource deployment is customized by editing @@ -24,7 +24,7 @@ # Initialize script="${BASH_SOURCE[0]}" -scriptDir="$( cd "$( dirname "${script}" )" && pwd )" +scriptDir="$(cd "$(dirname "${script}")" && pwd)" source ${scriptDir}/../common/utility.sh source ${scriptDir}/../common/validate.sh @@ -46,19 +46,26 @@ usage() { executeIt=false while getopts "ehi:o:u:d:" opt; do case $opt in - i) valuesInputFile="${OPTARG}" + i) + valuesInputFile="${OPTARG}" ;; - o) outputDir="${OPTARG}" + o) + outputDir="${OPTARG}" ;; - u) azureResourceUID="${OPTARG}" + u) + azureResourceUID="${OPTARG}" ;; - e) executeIt=true + e) + executeIt=true ;; - d) domainInputFile="${OPTARG}" + d) + domainInputFile="${OPTARG}" ;; - h) usage 0 + h) + usage 0 ;; - *) usage 1 + *) + usage 1 ;; esac done @@ -77,8 +84,8 @@ if [ "${missingRequiredOption}" == "true" ]; then usage 1 fi -if [ -z "${azureResourceUID}" ];then - azureResourceUID=`date +%s` +if [ -z "${azureResourceUID}" ]; then + azureResourceUID=$(date +%s) fi # @@ -96,13 +103,13 @@ fail() { initOutputDir() { aksOutputDir="$outputDir/weblogic-on-aks" - pvOutput="${aksOutputDir}/pv.yaml" + scOutput="${aksOutputDir}/azure-csi-nfs.yaml" pvcOutput="${aksOutputDir}/pvc.yaml" adminLbOutput="${aksOutputDir}/admin-lb.yaml" clusterLbOutput="${aksOutputDir}/cluster-lb.yaml" domain1Output="${aksOutputDir}/domain1.yaml" - removeFileIfExists ${pvOutput} + removeFileIfExists ${scOutput} removeFileIfExists ${pvcOutput} removeFileIfExists ${adminLbOutput} removeFileIfExists ${clusterLbOutput} @@ -130,9 +137,9 @@ initialize() { validationError "You must use the -o option to specify the name of an existing directory to store the generated yaml files in." fi - domainPVInput="${scriptDir}/azure-file-pv-template.yaml" - if [ ! -f ${domainPVInput} ]; then - validationError "The template file ${domainPVInput} for generating a persistent volume was not found" + storageClassInput="${scriptDir}/azure-csi-storageaccount-template.yaml" + if [ ! -f ${storageClassInput} ]; then + validationError "The template file ${storageClassInput} for generating a NFS storage class was not found" fi domainPVCInput="${scriptDir}/azure-file-pvc-template.yaml" @@ -166,7 +173,7 @@ initialize() { export azureStorageShareName="${namePrefix}-${azureStorageShareNameSuffix}-${azureResourceUID}" export imagePullSecretName="${namePrefix}${imagePullSecretNameSuffix}" export persistentVolumeClaimName="${namePrefix}-${persistentVolumeClaimNameSuffix}-${azureResourceUID}" - + export persistentVolumeId="${namePrefix}-${persistentVolumeClaimNameSuffix}-${azureResourceUID}" } # @@ -184,20 +191,20 @@ createYamlFiles() { # (if needed) and copy the inputs file there. copyInputsFileToOutputDirectory ${valuesInputFile} "${aksOutputDir}/create-domain-on-aks-inputs.yaml" - echo Generating ${pvOutput} + echo Generating ${scOutput} - cp ${domainPVInput} ${pvOutput} - sed -i -e "s:%PERSISTENT_VOLUME_NAME%:${persistentVolumeClaimName}:g" ${pvOutput} - sed -i -e "s:%AZURE_FILE_SHARE_SECRET_NAME%:${azureFileShareSecretName}:g" ${pvOutput} - sed -i -e "s:%AZURE_FILE_SHARE_NAME%:${azureStorageShareName}:g" ${pvOutput} - sed -i -e "s:%STORAGE_CLASS_NAME%:${azureStorageClassName}:g" ${pvOutput} + cp ${storageClassInput} ${scOutput} + sed -i -e "s:%STORAGE_CLASS_NAME%:${azureFileCsiNfsClassName}:g" ${scOutput} + sed -i -e "s:%AZURE_FILE_SHARE_NAME%:${azureStorageShareName}:g" ${scOutput} + sed -i -e "s:%STORAGE_ACCOUNT_RESOURCE_GROUP_NAME%:${azureResourceGroupName}:g" ${scOutput} + sed -i -e "s:%STORAGE_ACCOUNT_NAME%:${storageAccountName}:g" ${scOutput} # Generate the yaml to create the persistent volume claim echo Generating ${pvcOutput} cp ${domainPVCInput} ${pvcOutput} sed -i -e "s:%PERSISTENT_VOLUME_CLAIM_NAME%:${persistentVolumeClaimName}:g" ${pvcOutput} - sed -i -e "s:%STORAGE_CLASS_NAME%:${azureStorageClassName}:g" ${pvcOutput} + sed -i -e "s:%STORAGE_CLASS_NAME%:${azureFileCsiNfsClassName}:g" ${pvcOutput} # Generate the yaml to create WebLogic Server domain. echo Generating ${domain1Output} @@ -234,11 +241,11 @@ createYamlFiles() { # javaOptions may contain tokens that are not allowed in export command # we need to handle it differently. # we set the javaOptions variable that can be used later - tmpStr=`grep "javaOptions" ${exportValuesFile}` + tmpStr=$(grep "javaOptions" ${exportValuesFile}) javaOptions=${tmpStr//"javaOptions="/} # We exclude javaOptions from the exportValuesFile - grep -v "javaOptions" ${exportValuesFile} > ${tmpFile} + grep -v "javaOptions" ${exportValuesFile} >${tmpFile} source ${tmpFile} rm ${exportValuesFile} ${tmpFile} @@ -265,142 +272,164 @@ createYamlFiles() { } loginAzure() { - # login with a service principal - az login --service-principal --username $azureServicePrincipalAppId \ - --password $azureServicePrincipalClientSecret \ - --tenant $azureServicePrincipalTenantId - echo Login Azure with Servie Principal successfully. - - if [ $? -ne 0 ]; then - fail "Login to Azure failed!" - fi + # login with a service principal + az login --service-principal --username $azureServicePrincipalAppId \ + --password $azureServicePrincipalClientSecret \ + --tenant $azureServicePrincipalTenantId + echo Login Azure with Servie Principal successfully. + + if [ $? -ne 0 ]; then + fail "Login to Azure failed!" + fi } createResourceGroup() { - # Create a resource group - echo Check if ${azureResourceGroupName} exists - ret=$(az group exists --name ${azureResourceGroupName}) - if [ $ret != false ];then - fail "${azureResourceGroupName} exists, please change value of namePrefix to generate a new resource group name." - fi + # Create a resource group + echo Check if ${azureResourceGroupName} exists + ret=$(az group exists --name ${azureResourceGroupName}) + if [ $ret != false ]; then + fail "${azureResourceGroupName} exists, please change value of namePrefix to generate a new resource group name." + fi - echo Creating Resource Group ${azureResourceGroupName} - az group create --name $azureResourceGroupName --location $azureLocation + echo Creating Resource Group ${azureResourceGroupName} + az group create --name $azureResourceGroupName --location $azureLocation } createAndConnectToAKSCluster() { - # Create aks cluster - echo Check if ${aksClusterName} exists - ret=$(az aks list -g ${azureResourceGroupName} | grep "${aksClusterName}") - if [ -n "$ret" ];then - fail "AKS instance with name ${aksClusterName} exists." - fi + # Create aks cluster + echo Check if ${aksClusterName} exists + ret=$(az aks list -g ${azureResourceGroupName} | grep "${aksClusterName}") + if [ -n "$ret" ]; then + fail "AKS instance with name ${aksClusterName} exists." + fi - echo Creating Azure Kubernetes Service ${aksClusterName} - az aks create --resource-group $azureResourceGroupName \ - --name $aksClusterName \ - --vm-set-type VirtualMachineScaleSets \ - --node-count ${azureKubernetesNodeCount} \ - --generate-ssh-keys \ - --nodepool-name ${azureKubernetesNodepoolName} \ - --node-vm-size ${azureKubernetesNodeVMSize} \ - --location $azureLocation \ - --service-principal $azureServicePrincipalAppId \ - --client-secret $azureServicePrincipalClientSecret - - # Connect to AKS cluster - echo Connencting to Azure Kubernetes Service. - az aks get-credentials --resource-group $azureResourceGroupName --name $aksClusterName + echo Creating Azure Kubernetes Service ${aksClusterName} + az aks create --resource-group $azureResourceGroupName \ + --name $aksClusterName \ + --vm-set-type VirtualMachineScaleSets \ + --node-count ${azureKubernetesNodeCount} \ + --generate-ssh-keys \ + --nodepool-name ${azureKubernetesNodepoolName} \ + --node-vm-size ${azureKubernetesNodeVMSize} \ + --location $azureLocation \ + --service-principal $azureServicePrincipalAppId \ + --client-secret $azureServicePrincipalClientSecret + + # Connect to AKS cluster + echo Connencting to Azure Kubernetes Service. + az aks get-credentials --resource-group $azureResourceGroupName --name $aksClusterName } createFileShare() { - # Create a storage account - echo Check if the storage account ${storageAccountName} exists. - ret=$(az storage account check-name --name ${storageAccountName}) - nameAvailable=$(echo "$ret" | grep "nameAvailable" | grep "false") - if [ -n "$nameAvailable" ];then - echo $ret - fail "Storage account ${aksClusterName} is unavaliable." - fi + # Create a storage account + echo Check if the storage account ${storageAccountName} exists. + ret=$(az storage account check-name --name ${storageAccountName}) + nameAvailable=$(echo "$ret" | grep "nameAvailable" | grep "false") + if [ -n "$nameAvailable" ]; then + echo $ret + fail "Storage account ${aksClusterName} is unavailable." + fi - echo Creating Azure Storage Account ${storageAccountName}. - az storage account create \ - -n $storageAccountName \ - -g $azureResourceGroupName \ - -l $azureLocation \ - --sku ${azureStorageAccountSku} - - # Export the connection string as an environment variable, this is used when creating the Azure file share - export azureStorageConnectionString=$(az storage account show-connection-string \ - -n $storageAccountName -g $azureResourceGroupName -o tsv) - - # Create the file share - echo Check if file share exists - ret=$( az storage share exists --name ${azureStorageShareName} --account-name ${storageAccountName} --connection-string $azureStorageConnectionString | grep "exists" | grep false) - if [[ "$ret" == "true" ]];then - fail "File share name ${azureStorageShareName} is unavaliable." - fi + echo Creating Azure Storage Account ${storageAccountName}. + az storage account create \ + -n $storageAccountName \ + -g $azureResourceGroupName \ + -l $azureLocation \ + --sku Premium_LRS \ + --kind FileStorage \ + --https-only false \ + --default-action Deny + + echo Creating Azure NFS file share. + az storage share-rm create \ + --resource-group $azureResourceGroupName \ + --storage-account $storageAccountName \ + --name ${azureStorageShareName} \ + --enabled-protocol NFS \ + --root-squash NoRootSquash \ + --quota 100 + + configureStorageAccountNetwork + + # Echo storage account name and key + echo Storage account name: $storageAccountName + echo NFS file share name: ${azureStorageShareName} + + # Mount the file share as a volume + echo Mounting file share as a volume. + kubectl apply -f ${scOutput} + kubectl get storageclass ${azureFileCsiNfsClassName} -o yaml + kubectl apply -f ${pvcOutput} + kubectl get pvc ${persistentVolumeClaimName} -o yaml + + checkPvcState ${persistentVolumeClaimName} "Bound" +} + +configureStorageAccountNetwork() { + # get the resource group name of the AKS managed resources + local aksMCRGName=$(az aks show --name $aksClusterName --resource-group $azureResourceGroupName -o tsv --query "nodeResourceGroup") + echo ${aksMCRGName} - echo Creating Azure File Share ${azureStorageShareName}. - az storage share create -n $azureStorageShareName \ - --connection-string $azureStorageConnectionString - - # Get storage account key - azureStorageKey=$(az storage account keys list --resource-group $azureResourceGroupName \ - --account-name $storageAccountName --query "[0].value" -o tsv) - - # Echo storage account name and key - echo Storage account name: $storageAccountName - echo Storage account key: $azureStorageKey - - # Create a Kubernetes secret - echo Creating kubectl secret for Azure File Share ${azureFileShareSecretName}. - bash $dirKubernetesSecrets/create-azure-storage-credentials-secret.sh \ - -s ${azureFileShareSecretName} \ - -a $storageAccountName \ - -k $azureStorageKey - - # Mount the file share as a volume - echo Mounting file share as a volume. - kubectl apply -f ${pvOutput} - kubectl get pv ${persistentVolumeClaimName} -o yaml - kubectl apply -f ${pvcOutput} - kubectl get pvc ${persistentVolumeClaimName} -o yaml + # get network name of AKS cluster + local aksNetworkName=$(az resource list --resource-group ${aksMCRGName} --resource-type Microsoft.Network/virtualNetworks -o tsv --query '[*].name') + echo ${aksNetworkName} + + # get subnet name of AKS agent pool + local aksSubnetName=$(az network vnet subnet list --resource-group ${aksMCRGName} --vnet-name ${aksNetworkName} -o tsv --query "[*].name") + echo ${aksSubnetName} + + local aksSubnetId=$(az network vnet subnet list --resource-group ${aksMCRGName} --vnet-name ${aksNetworkName} -o tsv --query "[*].id") + echo ${aksSubnetId} + + az network vnet subnet update \ + --resource-group $aksMCRGName \ + --name ${aksSubnetName} \ + --vnet-name ${aksNetworkName} \ + --service-endpoints Microsoft.Storage + + az storage account network-rule add \ + --resource-group $azureResourceGroupName \ + --account-name $storageAccountName \ + --subnet ${aksSubnetId} + + if [ $? != 0 ]; then + fail "Fail to configure network for storage account ${storageAccountName}. Network name: ${aksNetworkName}. Subnet name: ${aksSubnetName}." + fi } installWebLogicOperator() { - echo `helm version` - helm repo add weblogic-operator https://oracle.github.io/weblogic-kubernetes-operator/charts - helm repo update - helm install weblogic-operator weblogic-operator/weblogic-operator --version "3.0.0" + echo $(helm version) + helm repo add weblogic-operator https://oracle.github.io/weblogic-kubernetes-operator/charts + helm repo update + helm install weblogic-operator weblogic-operator/weblogic-operator } createWebLogicDomain() { - # Create WebLogic Server Domain Credentials. - echo Creating WebLogic Server Domain credentials, with user ${weblogicUserName}, domainUID ${domainUID} - bash ${dirCreateDomainCredentials}/create-weblogic-credentials.sh -u ${weblogicUserName} \ - -p ${weblogicAccountPassword} -d ${domainUID} - - # Create Container Registry Credentials. - bash $dirKubernetesSecrets/create-docker-credentials-secret.sh \ - -e ${docker-email} \ - -p ${dockerPassword} \ - -u ${dockerUserName} \ - -s ${imagePullSecretName} \ - -d container-registry.oracle.com - - # Create WebLogic Server Domain - echo Creating WebLogic Server domain ${domainUID} - bash ${dirCreateDomain}/create-domain.sh -i $domain1Output -o ${outputDir} -e -v - - kubectl apply -f ${adminLbOutput} - kubectl apply -f ${clusterLbOutput} + # Create WebLogic Server Domain Credentials. + echo Creating WebLogic Server Domain credentials, with user ${weblogicUserName}, domainUID ${domainUID} + bash ${dirCreateDomainCredentials}/create-weblogic-credentials.sh -u ${weblogicUserName} \ + -p ${weblogicAccountPassword} -d ${domainUID} + + # Create Container Registry Credentials. + bash $dirKubernetesSecrets/create-docker-credentials-secret.sh \ + -e ${docker-email} \ + -p ${dockerPassword} \ + -u ${dockerUserName} \ + -s ${imagePullSecretName} \ + -d container-registry.oracle.com + + # Create WebLogic Server Domain + echo Creating WebLogic Server domain ${domainUID} + bash ${dirCreateDomain}/create-domain.sh -i $domain1Output -o ${outputDir} -e -v + + kubectl apply -f ${adminLbOutput} + kubectl apply -f ${clusterLbOutput} } waitForJobComplete() { - attempts=0 - svcState="running" - while [ ! "$svcState" == "completed" ] && [ ! $attempts -eq 30 ]; do + local attempts=0 + local svcState="running" + while [ ! "$svcState" == "completed" ] && [ ! $attempts -eq 30 ]; do svcState="completed" attempts=$((attempts + 1)) echo Waiting for job completed...${attempts} @@ -410,25 +439,25 @@ waitForJobComplete() { # ${domainUID}-${adminServerName}, e.g. domain1-admin-server # ${domainUID}-${adminServerName}-ext, e.g. domain1-admin-server-ext # ${domainUID}-${adminServerName}-external-lb, e.g domain1-admin-server-external-lb - adminServiceCount=`kubectl get svc | grep -c "${domainUID}-${adminServerName}"` + local adminServiceCount=$(kubectl get svc | grep -c "${domainUID}-${adminServerName}") if [ ${adminServiceCount} -lt 3 ]; then svcState="running"; fi # If the job is completed, there should have the following services created, .assuming initialManagedServerReplicas=2 # ${domainUID}-${managedServerNameBase}1, e.g. domain1-managed-server1 # ${domainUID}-${managedServerNameBase}2, e.g. domain1-managed-server2 - managedServiceCount=`kubectl get svc | grep -c "${domainUID}-${managedServerNameBase}"` + local managedServiceCount=$(kubectl get svc | grep -c "${domainUID}-${managedServerNameBase}") if [ ${managedServiceCount} -lt ${initialManagedServerReplicas} ]; then svcState="running"; fi # If the job is completed, there should have no service in pending status. - pendingCount=`kubectl get svc | grep -c "pending"` + local pendingCount=$(kubectl get svc | grep -c "pending") if [ ${pendingCount} -ne 0 ]; then svcState="running"; fi # If the job is completed, there should have the following pods running # ${domainUID}-${adminServerName}, e.g. domain1-admin-server - # ${domainUID}-${managedServerNameBase}1, e.g. domain1-managed-server1 + # ${domainUID}-${managedServerNameBase}1, e.g. domain1-managed-server1 # to # ${domainUID}-${managedServerNameBase}n, e.g. domain1-managed-servern, n = initialManagedServerReplicas - runningPodCount=`kubectl get pods | grep "${domainUID}" | grep -c "Running"` + local runningPodCount=$(kubectl get pods | grep "${domainUID}" | grep -c "Running") if [[ $runningPodCount -le ${initialManagedServerReplicas} ]]; then svcState="running"; fi echo ==============================Current Status========================================== @@ -440,8 +469,7 @@ waitForJobComplete() { # If all the services are completed, print service details # Otherwise, ask the user to refer to document for troubleshooting - if [ "$svcState" == "completed" ]; - then + if [ "$svcState" == "completed" ]; then kubectl get pods kubectl get svc else @@ -451,8 +479,11 @@ waitForJobComplete() { printSummary() { if [ "${executeIt}" = true ]; then - regionJsonExcerpt=`az group list --query "[?name=='${azureResourceGroupName}']" | grep location` - tokens=($(IFS='"'; for word in $regionJsonExcerpt; do echo "$word"; done)) + regionJsonExcerpt=$(az group list --query "[?name=='${azureResourceGroupName}']" | grep location) + tokens=($( + IFS='"' + for word in $regionJsonExcerpt; do echo "$word"; done + )) region=${tokens[2]} echo "" echo "" @@ -468,30 +499,30 @@ printSummary() { echo "" if [ "${exposeAdminNodePort}" = true ]; then - adminLbIP=`kubectl get svc ${domainUID}-${adminServerName}-external-lb --output jsonpath='{.status.loadBalancer.ingress[0].ip}'` + adminLbIP=$(kubectl get svc ${domainUID}-${adminServerName}-external-lb --output jsonpath='{.status.loadBalancer.ingress[0].ip}') echo "Administration console access is available at http://${adminLbIP}:${adminPort}/console" fi echo "" - clusterLbIP=`kubectl get svc ${domainUID}-${clusterName}-external-lb --output jsonpath='{.status.loadBalancer.ingress[0].ip}'` + clusterLbIP=$(kubectl get svc ${domainUID}-${clusterName}-external-lb --output jsonpath='{.status.loadBalancer.ingress[0].ip}') echo "Cluster external ip is ${clusterLbIP}, after you deploy application to WebLogic Server cluster, you can access it at http://${clusterLbIP}:${managedServerPort}/" fi echo "" echo "The following files were generated:" - echo " ${pvOutput}" + echo " ${scOutput}" echo " ${pvcOutput}" echo " ${adminLbOutput}" echo " ${clusterLbOutput}" echo " ${domain1Output}" echo "" - + echo "Completed" } cd ${scriptDir} cd .. -export dirSampleScripts=`pwd` +export dirSampleScripts=$(pwd) export dirCreateDomain="${dirSampleScripts}/create-weblogic-domain/domain-home-on-pv" export dirCreateDomainCredentials="${dirSampleScripts}/create-weblogic-domain-credentials" export dirKubernetesSecrets="${dirSampleScripts}/create-kubernetes-secrets" @@ -530,7 +561,7 @@ if [ "${executeIt}" = true ]; then # Create WebLogic Server Domain createWebLogicDomain - + # Wait for all the jobs completed waitForJobComplete fi diff --git a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/validate.sh b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/validate.sh index 7a83a925fe3..c1f72ceff73 100755 --- a/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/validate.sh +++ b/kubernetes/samples/scripts/create-weblogic-domain-on-azure-kubernetes-service/validate.sh @@ -10,9 +10,7 @@ # * Azure storage account: check if it is created # * Azure file share: check if it's created # * Kubernetes secret for container registry account: check if it's created -# * Kubernetes secret for storage account: check if it's created # * Kubernetes secret for WebLogic domain: check if it's created -# * Persistent Volume: check if it's mounted and verify the status and storage class # * Persistent Volume Claim: check if it's mounted and verify the status and storage class # Initialize @@ -27,10 +25,8 @@ usage() { echo " --storage-account [Required] :Storage account name." echo " --domain-uid -d [Required] :Domain UID." - echo " --pv-name [Required] : Persistent Volume name." - echo " --pvc-name [Required] : Persistent Volume Claim name." + echo " --pvc-name [Required] : Persistent Volume Claim name." echo " --secret-docker [Required] : Name of the Kubernetes secret that stores docker account." - echo " --secret-storage [Required] : Name of the Kubernetes secret that stores Azure storage file share credentials." echo " --help -h :Help" exit $1 } @@ -87,16 +83,6 @@ while test $# -gt 0; do fi shift ;; - --pv-name*) - shift - if test $# -gt 0; then - export pvName=$1 - else - echo "Persistent Volume name is required." - exit 1 - fi - shift - ;; --pvc-name*) shift if test $# -gt 0; then @@ -117,16 +103,6 @@ while test $# -gt 0; do fi shift ;; - --secret-storage*) - shift - if test $# -gt 0; then - export secretStorage=$1 - else - echo "Secret name for Storage is required." - exit 1 - fi - shift - ;; -h|--help) usage 0 ;; *) usage 1 @@ -147,10 +123,6 @@ if [ -z ${fileShare} ]; then echo "${script}: --file-share must be specified." missingRequiredOption="true" fi -if [ -z ${pvName} ]; then - echo "${script}: --pv-name must be specified." - missingRequiredOption="true" -fi if [ -z ${pvcName} ]; then echo "${script}: --pvc-name must be specified." missingRequiredOption="true" @@ -163,10 +135,6 @@ if [ -z ${secretDocker} ]; then echo "${script}: --secret-docker must be specified." missingRequiredOption="true" fi -if [ -z ${secretStorage} ]; then - echo "${script}: --secret-storage must be specified." - missingRequiredOption="true" -fi if [ -z ${storageAccount} ]; then echo "${script}: --storage-account must be specified." missingRequiredOption="true" @@ -219,7 +187,7 @@ validateFileShare() { -n $storageAccount -g $resourceGroup -o tsv) echo Check if file share exists - ret=$( az storage share exists --name ${fileShare} --account-name ${storageAccount} --connection-string $azureStorageConnectionString | grep "exists" | grep false) + ret=$( az storage share-rm exists --name ${fileShare} --storage-account ${storageAccount} | grep "exists" | grep false) if [ -n "$ret" ];then fail "File share ${fileShare} is unavailable." fi @@ -239,44 +207,15 @@ validateDockerSecret() { fi } -validateStorageSecret() { - kubectl get secret ${secretStorage} - if [ $? -ne 0 ]; then - fail "Secret:${secretStorage} for storage is not created." - fi -} - validateWebLogicDomainSecret() { ret=$(kubectl get secrets | grep "weblogic-credentials") if [ $? -ne 0 ]; then - fail "Secret:${secretStorage} for storage is not created." + fail "Secret:weblogic-credentials is not created." fi export secretWebLogic=$(echo ${ret%% *}) } -validatePV() { - ret=$(kubectl get pv) - index=0 - for item in ${ret}; - do - index=$((index + 1)) - if [ $index -eq 12 ]; then - if [[ "$item" != "$pvName" ]];then - fail "Persistent Volume name $item does not match value $pvName." - fi - fi - - if [[ $index -eq 16 && "$item" != "Bound" ]]; then - fail "Persistent Volume status is not Bound." - fi - - if [[ $index -eq 18 && "$item" != "azurefile" ]]; then - echo "WARNING" "Storage class $item does not match azurefile, please check." - fi - done -} - validatePVC() { ret=$(kubectl get pvc) index=0 @@ -285,16 +224,12 @@ validatePVC() { index=$((index + 1)) if [ $index -eq 9 ]; then if [[ "$item" != "$pvcName" ]];then - fail "Persistent Volume name $item does not match value $pvcName." + fail "Persistent Volume Claim name $item does not match value $pvcName." fi fi if [[ $index -eq 10 && "$item" != "Bound" ]]; then - fail "Persistent Volume status is not Bound." - fi - - if [[ $index -eq 14 && "$item" != "azurefile" ]]; then - echo "WARNING" "Storage class $item does not match azurefile, please check." + fail "Persistent Volume Claim status is not Bound." fi done } @@ -321,10 +256,8 @@ pass() { echo " Azure Kubernetes Service instance: ${aksName}" echo " Azure storage account: ${storageAccount}" echo " Azure file share: ${fileShare}" - echo " Kubernetes secret for Azure storage: ${secretStorage}" echo " Kubernetes secret for Container Registry Account: ${secretDocker}" echo " Kubernetes secret for WebLogic domain: ${secretWebLogic}" - echo " Persistent Volume: ${pvName}" echo " Persistent Volume Claim: ${pvcName}" } @@ -342,12 +275,8 @@ connectAKS validateDockerSecret -validateStorageSecret - validateWebLogicDomainSecret -validatePV - validatePVC validateOperator