Skip to content

Commit

Permalink
WebLogic Kubernetes domain sample (oracle#668)
Browse files Browse the repository at this point in the history
* Change FMW 12.2.1.3 image to call the correct script to start domain.

* WebLogic Kubernetes domain sample

* Changes to the wls-k8s-domain image
  • Loading branch information
mriccell authored and brunoborges committed Nov 28, 2017
1 parent d52ffab commit 2385aeb
Show file tree
Hide file tree
Showing 15 changed files with 842 additions and 0 deletions.
28 changes: 28 additions & 0 deletions OracleWebLogic/samples/wls-k8s-domain/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

# Pull base image
# ---------------
FROM oracle/weblogic:12.2.1.3-developer

MAINTAINER Lily He <[email protected]>

# Environment variables required for this build (do NOT change)
# -------------------------------------------------------------
ENV MW_HOME="$ORACLE_HOME" \
PATH="$PATH:$ORACLE_HOME/wlserver/samples/server/:$ORACLE_HOME/wlserver/server/bin:$ORACLE_HOME/wlserver/../oracle_common/modules/org.apache.ant_1.9.2/bin" \
WLST="$ORACLE_HOME/oracle_common/common/bin/wlst.sh" \
DOMAIN_NAME=wlsdomain \
SAMPLE_DOMAIN_HOME=/u01/wlsdomain \
ADMIN_PORT=8001

USER root
# Copy scripts and install python http lib
# --------------------------------
COPY container-scripts/ /u01/oracle/
RUN chmod +x /u01/oracle/*.sh /u01/oracle/*.py

# install requests module of python since we need it to call REST api
RUN yum -y install python-requests && \
rm -rf /var/cache/yum

USER oracle
WORKDIR $SAMPLE_DOMAIN_HOME
136 changes: 136 additions & 0 deletions OracleWebLogic/samples/wls-k8s-domain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
WebLogic Sample on Kubernetes with Shared Domain Home
=========================================
This sample extends the Oracle WebLogic developer install image by creating a sample WLS 12.2.1.3 domain and cluster to run in Kubernetes. The WebLogic domain consists of an Admininstrator Server and several Managed Servers running in a WebLogic cluster. All WebLogic servers share the same domain home which has been mapped to an external volume.

## Prerequisites
1. You need to have a Kubernetes cluster up and running with kubectl installed.
2. You have built oracle/weblogic:12.2.1.3-developer image locally based on Dockerfile and scripts here: https://github.com/oracle/docker-images/tree/master/OracleWebLogic/dockerfiles/12.2.1.3/
3. Username/password for the WebLogic domain are stored in k8s/secrets.yml and they are encoded by base64. The default values are weblogic/weblogic1.
If you want to customize it, first get the encoded data of your username/password via running `echo -n <username> | base64` and `echo -n <password> | base64`. Next upate k8s/secrets.yml with the new encoded data.

## How to Build and Run

### 1. Build the WebLogic Image for This Sample Domain
Build the image:
```
$ docker build -t wls-k8s-domain .
```
If you run `docker build` behind a proxy, you need to set proxy settings via `--build-arg`.

### 2. Prepare Volume Directories
Three volumes are defined in `k8s/pv.yml` which refer to three external directories. You can choose to use host paths or shared NFS directories. Please change the paths accordingly. The external directories need to be initially empty.

**NOTE:** The first two persistent volumes `pv1` and `pv2` will be used by WebLogic server pods. All processes in WebLogic server pods are running with UID 1000 and GID 1000 by default, so proper permissions need to be set to these two external directories to make sure that UID 1000 or GID 1000 have permission to read and write the volume directories. The third persistent volume `pv3` is reserved for later use. We assume that root user will be used to access this volume so no particular permission need to be set to the directory.

### 3. Deploy All the Kubernetes Resources

Run the following commands to deploy the Kubernetes resources:
```
$ kubectl create -f k8s/secrets.yml
$ kubectl create -f k8s/pv.yml
$ kubectl create -f k8s/pvc.yml
$ kubectl create -f k8s/wls-admin.yml
$ kubectl create -f k8s/wls-stateful.yml
```

### 4. Check Resources Deployed to Kubernetes
#### 4.1 Check Pods and Controllers
List all pods and controllers:
```
$ kubectl get all
NAME READY STATUS RESTARTS AGE
po/admin-server-1238998015-f932w 1/1 Running 0 11m
po/managed-server-0 1/1 Running 0 11m
po/managed-server-1 1/1 Running 0 8m
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/admin-server 10.102.160.123 <nodes> 8001:30007/TCP 11m
svc/kubernetes 10.96.0.1 <none> 443/TCP 39d
svc/wls-service 10.96.37.152 <nodes> 8011:30009/TCP 11m
svc/wls-subdomain None <none> 8011/TCP 11m
NAME DESIRED CURRENT AGE
statefulsets/managed-server 2 2 11m
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deploy/admin-server 1 1 1 1 11m
NAME DESIRED CURRENT READY AGE
rs/admin-server-1238998015 1 1 1 11m
```

#### 4.2 Check PV and PVC
List all pv and pvc:
```
$ kubectl get pv
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 10Gi RWX Recycle Available manual 17m
pv2 10Gi RWX Recycle Bound default/wlserver-pvc-1 manual 17m
pv3 10Gi RWX Recycle Bound default/wlserver-pvc-2 manual 17m
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE
wlserver-pvc-1 Bound pv2 10Gi RWX manual 18m
wlserver-pvc-2 Bound pv3 10Gi RWX manual 18m
```

#### 4.3 Check Secrets
List all secrets:
```
$ kubectl get secrets
NAME TYPE DATA AGE
default-token-m93m1 kubernetes.io/service-account-token 3 39d
wlsecret Opaque 2 19m
```

### 5. Check Weblogic Server Status via Administrator Console
The admin console URL is 'http://[hostIP]:30007/console'.

### 6. Troubleshooting
You can trace WebLogic server output and logs for troubleshooting.

Trace WebLogic server output. Note you need to replace $serverPod with the actual pod name.
```
$ kubectl logs -f $serverPod
```
You can look at the WebLogic server logs by running:
```
$ kubectl exec managed-server-0 -- tail -f /u01/wlsdomain/servers/managed-server-0/logs/managed-server-0.log
$ kubectl exec managed-server-0 -- tail -f /u01/wlsdomain/servers/managed-server-1/logs/managed-server-1.log
$ kubectl exec managed-server-0 -- tail -f /u01/wlsdomain/servers/AdminServer/logs/AdminServer.log
```

### 7. Restart Pods
You may need to restart some or all of the WebLogic Server pods, for instance, you make some configuration change which can not be applied dynamically.

#### 7.1 Shutdown the Managed Servers' Pods Gracefully
```
$ kubectl exec -it managed-server-0 -- /u01/wlsdomain/bin/stopManagedWebLogic.sh managed-server-0 t3://admin-server:8001
$ kubectl exec -it managed-server-1 -- /u01/wlsdomain/bin/stopManagedWebLogic.sh managed-server-1 t3://admin-server:8001
```
#### 7.2 Shutdown the Administrator Server Pod Gracefully
First gracefully shutdown admin server process. Note that you need to replace $adminPod with the real admin server pod name.
```
$ kubectl exec -it $adminPod -- /u01/wlsdomain/bin/stopWebLogic.sh <username> <password> t3://localhost:8001
```
Next manually delete the admin pod.
```
$ kubectl delete pod/$adminPod
```
After the pods are stopped, each pod's corresponding controller is responsible for restarting the pods automatically.
Wait until all pods are running and ready again. Monitor status of pods via `kubectl get pod`.

### 8. Cleanup
Remove all resources from your Kubernetes cluster by running:
```
$ kubectl delete -f k8s/wls-stateful.yml
$ kubectl delete -f k8s/wls-admin.yml
$ kubectl delete -f k8s/pvc.yml
$ kubectl delete -f k8s/pv.yml
$ kubectl delete -f k8s/secrets.yml
```
You can now delete all of data generated to the external directories.
## COPYRIGHT
Copyright (c) 2014-2017 Oracle and/or its affiliates. All rights reserved.

6 changes: 6 additions & 0 deletions OracleWebLogic/samples/wls-k8s-domain/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
#Copyright (c) 2014-2017 Oracle and/or its affiliates. All rights reserved.
#
#Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
#
docker build -t wls-k8s-domain .
104 changes: 104 additions & 0 deletions OracleWebLogic/samples/wls-k8s-domain/container-scripts/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#Copyright (c) 2014-2017 Oracle and/or its affiliates. All rights reserved.
#
#Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
#
# Author Lily He

import requests
from requests.auth import HTTPBasicAuth
import json
import shutil
import sys
import os
from time import time
from time import sleep
from collections import OrderedDict
import os

adminPort=os.environ["ADMIN_PORT"]
prefix='http://localhost:' + adminPort + '/management/weblogic/latest/'
domainDir=os.environ["SAMPLE_DOMAIN_HOME"]
jmsFileName="mymodule-jms.xml"
jdbcFileName="ds1-jdbc.xml"

print (prefix, domainDir)

user = os.environ["WLUSER"]
pwd = os.environ["WLPASSWORD"]
auth = HTTPBasicAuth(user, pwd)
header1 = {'X-Requested-By': 'pythonclient','Accept':'application/json','Content-Type':'application/json'}
header2 = {'X-Requested-By': 'pythonclient','Accept':'application/json'}

def delete(tail):
myResponse = requests.delete(prefix+tail, auth=auth, headers=header2, verify=True)
result(myResponse, 'delete', 'false')

def get(tail):
myResponse = requests.get(prefix+tail, auth=auth, headers=header2, verify=True)
result(myResponse, 'get', 'false')
return myResponse

def result(res, opt, fail):
print (res.status_code)
if(not res.content.isspace()):
print (res.content)
if(res.ok):
print opt, 'succeed.'
else:
print opt, 'failed.'
if(fail == 'true'):
res.raise_for_status()

def waitAdmin():
print("wait until admin started")
tail='domainRuntime/serverRuntimes/'
fail = True
while(fail):
sleep(2)
try:
res = requests.get(prefix+tail, auth=auth, headers=header2, verify=True)
print res.status_code
if(res.ok):
fail=False
except Exception:
print "waiting admin started..."

def cpJMSResource(modulefile):
print("cpJMSResource", modulefile)
destdir=domainDir+'/config/jms/'
try:
os.makedirs(destdir)
except OSError:
if not os.path.isdir(destdir):
raise
destfile=destdir + jmsFileName
shutil.copyfile(modulefile, destfile)
print('copy jms resource finished.')

def cpJDBCResource(modulefile):
print("cpJDBCResource", modulefile)
destdir=domainDir+'/config/jdbc/'
try:
os.makedirs(destdir)
except OSError:
if not os.path.isdir(destdir):
raise
destfile=destdir + jdbcFileName
shutil.copyfile(modulefile, destfile)
print('copy jdbc resource finished. from', modulefile, 'to', destfile)

def createOne(name, tail, data):
#print("create", name, tail, data)
jData = json.dumps(data, ensure_ascii=False)
print(jData)
myResponse = requests.post(prefix+"edit/"+tail, auth=auth, headers=header1, data=jData, verify=True)
result(myResponse, 'create ' + name, 'true')

def createAll(inputfile):
jdata = json.loads(open(inputfile, 'r').read(), object_pairs_hook=OrderedDict)
for tkey in jdata.keys():
ss =jdata.get(tkey)
for key in ss.keys():
oneRes = ss.get(key)
print(oneRes)
createOne(key, oneRes['url'], oneRes['data'])
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{ "resources": {
"myCluster": {
"url": "clusters",
"data": {
"migrationBasis": "database",
"clusterMessagingMode": "unicast",
"name": "myCluster"
}
},

"ds1": {
"url": "JDBCSystemResources",
"data": {
"targets":[{
"identity":["clusters", "myCluster"]
}],
"descriptorFileName": "jdbc/ds1-jdbc.xml",
"name": "ds1"
}
},

"updateCluster": {
"url": "clusters/myCluster",
"data": {
"dataSourceForAutomaticMigration": ["JDBCSystemResources", "ds1"]
}
},

"managed-server-0": {
"url": "servers",
"data": {
"listenPort": 8011,
"listenAddress": "managed-server-0.wls-subdomain.default.svc.cluster.local",
"cluster": ["clusters", "myCluster"],
"name": "managed-server-0"
}
},

"managed-server-1": {
"url": "servers",
"data": {
"listenPort": 8011,
"listenAddress": "managed-server-1.wls-subdomain.default.svc.cluster.local",
"cluster": ["clusters", "myCluster"],
"name": "managed-server-1"
}
},

"managed-server-2": {
"url": "servers",
"data": {
"listenPort": 8011,
"listenAddress": "managed-server-2.wls-subdomain.default.svc.cluster.local",
"cluster": ["clusters", "myCluster"],
"name": "managed-server-2"
}
},

"managed-server-3": {
"url": "servers",
"data": {
"listenPort": 8011,
"listenAddress": "managed-server-3.wls-subdomain.default.svc.cluster.local",
"cluster": ["clusters", "myCluster"],
"name": "managed-server-3"
}
}

}}

Loading

0 comments on commit 2385aeb

Please sign in to comment.