Friday 24 January 2020

My Weblogic on Kubernetes Cheatsheet, part 2.

In my previous blog-post I published the first part of my Kubernetes cheatsheet, following the Weblogic Operator tutorial. In this part 2, I'll publish the scripts I created for the next few chapters in the tutorial.

Install Traefik Software Loadbalancer

The fourth part of the tutorial is about installing the Treafic Software Loadbalancer service. It is described in this part: 3. Install Traefik Software Loadbalancer. And also uses Helm to install the service.

install_traefik.sh

Install Treafik is just a quest of (nice Dutch idiom 😉) installing the proper Helm chart.
#!/bin/bash
SCRIPTPATH=$(dirname $0)
#
. $SCRIPTPATH/oke_env.sh
echo Install traefik
cd $HELM_CHARTS_HOME
helm install stable/traefik \
--name traefik-operator \
--namespace traefik \
--values kubernetes/samples/charts/traefik/values.yaml  \
--set "kubernetes.namespaces={traefik}" \
--set "serviceType=LoadBalancer"
cd $SCRIPTPATH

getsvclbr.sh

A simple script to check the Loadbalancer Service:
#!/bin/bash
SCRIPTPATH=$(dirname $0)
#
. $SCRIPTPATH/oke_env.sh
echo Get service traefik
kubectl get service -n traefik

I did not change the name or the namespace of the Treafik loadbalancer. But I could do easily by moving the name and namespace to the oke_env.sh. But I haven't had the need, but I can imagine that it could raise.

getpublicip.sh

The scriptlet above will show all the treafik information. But to show only the public IP that you need to get to your application, you can use:
#!/bin/bash
SCRIPTPATH=$(dirname $0)
#
. $SCRIPTPATH/oke_env.sh
echo Get traefik public IP
kubectl describe svc traefik-operator --namespace traefik | grep Ingress | awk '{print $3}'

Again, I could move the serivce name and namespace to oke_env.sh.
When the Weblogic domain is created, there will be some additional commands and therefor scriptlets, that update the Treafik configuration.

Deploy WebLogic Domain

Now it gets really interesting: we're getting to create the actual Weblogic pods that will run the Weblogic Domain. This part is described in the fifth part: Deploy Weblogic Domain.

create_wlsdmnaccount.sh

This script will do a sequence of things. You could argue that several of the scripts described earlier could have been combined, like this.
Anyway,  this one does the following:
  • Create a Weblogic Domain Namespace
  • Create and label a Kubernetes secret within that namespace for the Admin boot credentials.
  • Create a secriet for the Docker registry on the Oracle infrastructure (Oracle Container Image Repository).
#!/bin/bash
SCRIPTPATH=$(dirname $0)
#
. $SCRIPTPATH/oke_env.sh
#
function prop {
    grep "${1}" $SCRIPTPATH/credentials.properties|cut -d'=' -f2
}
#
echo Create weblogic domain namespace $WLS_DMN_NS
kubectl create namespace $WLS_DMN_NS
WLS_USER=$(prop 'weblogic.user')
WLS_PWD=$(prop 'weblogic.password')
echo Create a Kubernetes secret $WLS_DMN_CRED in namespace $WLS_DMN_NS containing the Administration Server boot credentials for user $WLS_USER
kubectl -n $WLS_DMN_NS create secret generic $WLS_DMN_CRED \
  --from-literal=username=$WLS_USER \
  --from-literal=password=$WLS_PWD
echo Label the $WLS_DMN_CRED in namespace $WLS_DMN_NS secret with domainUID $WLS_DMN_NAME
kubectl label secret $WLS_DMN_CRED \
  -n $WLS_DMN_NS \
  weblogic.domainUID=$WLS_DMN_NAME \
  weblogic.domainName=$WLS_DNM_NAME \
  --overwrite=true
echo Create secret for oci image repository $OCIR_CRED
OCIR_USER=$(prop 'ocir.user')
OCIR_PWD=$(prop 'ocir.password')
OCIR_EMAIL=$(prop 'ocir.email')
OCI_TEN=$(prop 'oci.tenancy')
OCI_REG=$(prop 'oci.region')
kubectl create secret docker-registry $OCIR_CRED \
  -n $K8S_NS \
  --docker-server=${OCI_REG}.ocir.io \
  --docker-username="${OCI_TEN}/${OCIR_USER}" \
  --docker-password="${OCIR_PWD}" \
  --docker-email="${OCIR_EMAIL}"


The scripts starts with a function to read credential properties. It relies on the credentials.properties file:
weblogic.user=weblogic
weblogic.password=welcome1
ocir.user=that.would.be.me
ocir.password=something difficult
ocir.email=my.email.adres@darwin-it.nl
oci.tenancy=ours
oci.region=fra
db.medrec.username=MEDREC_OWNER
db.medrec.password=Medrec_Password$83!
db.medrec.url=jdbc:oracle:thin:@10.0.10.6:1521/pdb1.sub50abc021b.medrecokecluste.oraclevcn.com

I like the way this works with the prop function, because you can abstract these properties without the need to have them as a environment variable. Especially credentials you would not have in an en environment variable. Actually, passwords should be stored even more secure than in a plain property file, of course. But, I think I would move the OCID's used in seting up the OKE cluster to the credentials.properties in a next iteration.

upgrade_traefik.sh

When the Weblogic domain namespace is created, you can add it to the Treafik configuration:

#!/bin/bash
SCRIPTPATH=$(dirname $0)
#
. $SCRIPTPATH/oke_env.sh
echo Upgrade traefik with namespace $WLS_DMN_NS
cd $HELM_CHARTS_HOME
helm upgrade \
  --reuse-values \
  --set "kubernetes.namespaces={traefik,$WLS_DMN_NS}" \
  --wait \
  traefik-operator \
  stable/traefik

cd $SCRIPTPATH

start_dmn.sh

The next step in the tutorial is to create the Weblogic Domain by starting the pods. To do so, you need to create a domain.yaml, as in this example. You'll need to update the properties according to your environment, specifying things like the project domain container image, names, credential sets, etc.
For this script, one property is of special interest:
  # - "NEVER" will not start any server in the domain
  # - "ADMIN_ONLY" will start up only the administration server (no managed servers will be started)
  # - "IF_NEEDED" will start all non-clustered servers, including the administration server and clustered servers up to the replica count
  serverStartPolicy: "IF_NEEDED"

The property serverStartPolicy defines if the Weblogic pods should start or stop. To have them started, you would set the property to "IF_NEEDED" and to stop to "NEVER". I found that I had to change this property several times and then run kubectl apply on the yaml. Soon I thought that this should be more convenient. So I created a copy of the domain.yaml, called domain.yaml.tpl. In that file I changed the property to:
  # - "NEVER" will not start any server in the domain
  # - "ADMIN_ONLY" will start up only the administration server (no managed servers will be started)
  # - "IF_NEEDED" will start all non-clustered servers, including the administration server and clustered servers up to the replica count
  serverStartPolicy: "$SVR_STRT_POLICY"
  #serverStartPolicy: "NEVER"

Now using a script I can create a copy of the domain.yaml.tpl to domain.yaml while replacing the environment variable to the desired value. A few years ago I found the Linux command envsubst that can read in a file from stndin to replace all the environment variables with there corresponding value and output the result to stdout.

So to start the domain, I would use:
#!/bin/bash
SCRIPTPATH=$(dirname $0)
#
. $SCRIPTPATH/oke_env.sh
echo Start Domain $K8S_DMN_NAME
export SVR_STRT_POLICY="IF_NEEDED"
WLS_DMN_YAML_TPL=${WLS_DMN_YAML}.tpl
envsubst < $WLS_DMN_YAML_TPL > $WLS_DMN_YAML
kubectl apply -f $WLS_DMN_YAML

It will set the SVR_STRT_POLICY to "IF_NEEDED", and then streams the domain.yaml.tpl to the domain.yaml through envsubst. Then perform kubectl apply on the resulting yaml.
Obviously, you can use this also to abstract properties as cluster replicas and java options out of the yaml file and have them in a property file or oke_env.sh.

stop_dmn.sh


And of course, the stopping the domain will work accordingly, but then using the value "NEVER".
#!/bin/bash
SCRIPTPATH=$(dirname $0)
#
. $SCRIPTPATH/oke_env.sh
echo Stop Domain $K8S_DMN_NAME
export SVR_STRT_POLICY="NEVER"
WLS_DMN_YAML_TPL=${WLS_DMN_YAML}.tpl
envsubst < $WLS_DMN_YAML_TPL > $WLS_DMN_YAML
kubectl apply -f $WLS_DMN_YAML

upgrade_traefik_routing.sh


When your domain is started, you probably want to be able to reach it from out of the internet. To do so you need to create an Ingress rule. This is done as follows:
#!/bin/bash
SCRIPTPATH=$(dirname $0)
#
. $SCRIPTPATH/oke_env.sh
echo Upgrade traefik with namespace $WLS_DMN_NS
cat << EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-pathrouting-1
  namespace: $WLS_DMN_NS
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host:
    http:
      paths:
      - path: /
        backend:
          serviceName: medrec-domain-cluster-medrec-cluster
          servicePort: 8001
      - path: /console
        backend:
          serviceName: medrec-domain-adminserver
          servicePort: 7001          
EOF

The thing with this script is that it does not leverage the oke_env.sh script, except for the namespace. There are still a few hardcoded names for the service and the Ingress names. But, just like the namespace, it is easy to move those to the oke_env.sh script.

getdmnpods.sh


When started your domain, you would check the pods. This can be done with this script:
#!/bin/bash
SCRIPTPATH=$(dirname $0)
#
. $SCRIPTPATH/oke_env.sh
echo Get K8s pods for $WLS_DMN_NS
kubectl -n $WLS_DMN_NS get pods -o wide

Initially, you would see 3 pods, one for the Admin server and two Managed servers. But after changing the domain.yaml.tpl following the sixth part: Scaling WebLogic Cluster, you would see more (or less) pods. Mind that if you use my start and stop scripts, you should not change the domain.yaml file itself but the domain.yaml.tpl file.

Conclusion

These scripts helped me a lot in documenting the setup. You can just follow the tutorial, which leaves you with a working environment. But it's just a recipe that you need to follow over and over again. Also, I found at a few points that it is tricky to fill in the correct value.

Lately, I started to look into Terraform for AWS and OCI. I figure that the tutorial that I followed with these scripts can be broken down into a few parts that are infact setting up OCI resources (Instances, Services like Treafik, etc.) and provisioning OKE. So it would be interesting to see where we can use Terraform to setup the OCI resources and services, leaving only the scripts to setup OKE itself.





No comments :