Tagged KUBERNETES

“Kool” Kubernetes Client Tools


When working with k8s, you typically have several clusters and a bunch of namespaces per cluster, the following tools can help you manage the stuff with easy.

kubectx + kubens

kubectx allows you to change the context between different k8s clusters

kubens allows you to change between different namespaces in the current cluster context

brew install kubectx

More info here

Kube-ps1

Allows you to see the current context and namespace in the promt

brew install kube-ps1

More info here

Examples

kubectx, kubens and kube-ps1 at a glance

kubeaudit

Great tool for auditing the security settings on your k8s clusters

brew install kubeaudit
kubeaudit allowpe

krew

Krew is a package manager for kubectl (kubectl has an extensibility framework and this tool helps manage extensions)

Hope it helps! 🙂

Set Up an Ingress Controller in OKE Cluster


Step 1: setting up the nginx ingress controller

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

Step 2: exposing the ingress as a service of type LoadBalancer (as a public IP)

kubectl apply -f https://raw.githubusercontent.com/javiermugueta/rawcontent/master/cloud-generic.yaml

Step 3: Execute this command several times until the external-ip appears as non <pending>, grab the IP for later testing

kubectl get svc -n ingress-nginx

Step 4: a certificate for ssl termination

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"


kubectl create secret tls tls-secret --key tls.key --cert tls.crtopenssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"

Step 5

kubectl create -f https://raw.githubusercontent.com/javiermugueta/rawcontent/master/hello-world-ingress.yaml

Step 6: A typical hello world deployment with a pod in it and 3 replicas

kubectl create -f https://raw.githubusercontent.com/javiermugueta/rawcontent/master/ingress.yaml

Step 7: Test the url and see what happens…

That’s all folks! Hope it helps 🙂

Deploying a Coherence Cluster in Kubernetes


Coherence-Operator is a Kubernetes opeartor for deploying Oracle Coherence in k8s. Let’s see how to do it.

1 Clean previous setup intents:

helm del --purge sample-coherence
helm del --purge sample-coherence-operator
kubectl delete namespace sample-coherence-ns

2 Execute the following:

kubectl config set-context $(kubectl config current-context) --namespace=sample-coherence-ns

helm repo add coherence https://oracle.github.io/coherence-operator/charts

helm repo update

helm --debug install coherence/coherence-operator --name sample-coherence-operator --set "targetNamespaces={}" --set imagePullSecrets=sample-coherence-secret

helm ls

helm status sample-coherence-operator

3 Create a secret with your credentials to Oracle Container Registry:

kubectl create secret docker-registry oracle-container-registry-secret --docker-server=container-registry.oracle.com --docker-username='youruser' --docker-password='yourpasswd' --docker-email='youremail'

4 Install:

helm --debug install coherence/coherence --name sample-coherence --set imagePullSecrets=oracle-container-registry-secret

5 Proxy to a pod:

export POD_NAME=$(kubectl get pods --namespace sample-coherence-ns -l "app=coherence,release=sample-coherence,component=coherencePod" -o jsonpath="{.items[0].metadata.name}")

kubectl --namespace sample-coherence-ns port-forward $POD_NAME 20000:20000

6 Download and install Coherence Stand Alone

7 Download this and this

8 Build the client:

export COHERENCE_HOME=~/Oracle/Middleware/Oracle_Home/coherence
javac -cp .:${COHERENCE_HOME}/lib/coherence.jar HelloCoherence.javaexport COHERENCE_HOME=~/Oracle/Middleware/Oracle_Home/coherence

9 Test it:

java -cp .:${COHERENCE_HOME}/lib/coherence.jar -Dcoherence.cacheconfig=$PWD/example-client-config.xml HelloCoherence

2019-07-11 01:21:33.575/0.538 Oracle Coh...

…

Oracle Coherence Version 12.2.1.3.0 Build 68243

2019-07-11 01:21:34.430/1.392 Oracle 

The value of the key is 7

That’s all, hope it helps 🙂

Shared Disk Seen by Pods Deployed in two Independent OKE Clusters across two Cloud Regions | Remote Network Peering


In this episode we are creating 2 independent OKE clusters, one in Frankfurt and the other in Phoenix, and then we will create a File System in Frankfurt (kind of NFS server) that will act as repository for a shared persistent volume reachable by all the pods of a deployment deployed to both clusters.

Remote Peering

Oracle Cloud Infrastructure networking provides “Remote Peering”, which allows the connection between networks (Virtual Cloud Networks -VCN-) in two different cloud regions.

Peering the 2 VCN’s

Let’s create one VCN in Frankfurt and other in another region, Phoenix in my case.

IMPORTANT: VCN CIDR’s must not overlap!

Now create a DRG in Frankfurt, then create a Remote Peering Connection (RPC):

Do the same in Phoenix and grab the OCID of the new RPC created, we’ll need it in the next step:

Come back to the RPC in Frankfurt, click [Establish Connection], select the region and paste the OCID of the remote RPC:

After a while you should be the status PEERED in both RPC’s:

Now, attach the VCN to the DRG in both sides:

So far, sogood! The 2 VCN’s are peered, now let’s manage how the networks can reach each other, how? – by routing them! We are going to create the routes with OCI CLI (because at the moment of this writing I wasn’t able to create them with the GUI). To do it grab previously the following info from both regions:

  • compartment-OCID
  • vcn-OCID
  • drg-OCIID

Now let’s create a route from fra to phx:

oci network route-table create --compartment-id [yourcompartmentocid] --vcn-id [yourvcnocid] --route-rules '[{"cidrBlock":"192.168.0.0/16","networkEntityId":"[yourdrgocid]"}]'

And now from phx to fra:

oci network route-table create --compartment-id [yourcompartmentocid] --vcn-id [yourvcnocid] --route-rules '[{"cidrBlock":"10.0.0.0/16","networkEntityId":"[yourdrgocid]"}]' --region us-phoenix-1

Please note the CIDR block parameter I’ve put (remarked in bold), which in this case is the CIDR of the whole VCN, because we want to route to all the subnets on each side. The routes created look like this:

Now we must modify the routes created on each region and add a rule for the nodes in the private subnet so that they can reach the internet via a NAT gateway, because if not, k8s can’t reach the docker container repo I’m using (you must create one NAT gateway on each side just in case you have not already done it):

Now we must assign to each one of the private subnets on each VCN the route tables created on each region:

Now create a K8S cluster on each region (use the custom option because you must select the VCN’s you have created previously).

Now follow this post to create the shared file system in Frankfurt.

One more thing, configure security list to allow traffic, NFS ports are:

UDP: 111,1039,1047,1048,2049
TCP: 111,1039,1047,1048,2049

Soo faaar sooo goood! We have the VCN networks peered, DRG’s created, VCN’s attached to DRG’s, routes created, NFS traffic allowed, storage ready and k8s clustered created!

Finally deploy this to both k8s clusters. NOTE: modify the yaml with the specific values of IP and export of your own File System:

kubectl apply -f k8spod2nfs.yaml

Now ssh to one of the pods in the Phoenix cluster and verify you can see the shared content. Then modify the index.html file and dump the content of the file. Finally get the public IP of the service created.

MacBook-Pro:k8spod2nfs javiermugueta$ kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
k8spod2nfs-6c6665479f-b6q8j   1/1     Running   0          1m
k8spod2nfs-6c6665479f-md5s5   1/1     Running   0          1m
MacBook-Pro:k8spod2nfs javiermugueta$ kubectl exec -it k8spod2nfs-6c6665479f-b6q8j bash
root@k8spod2nfs-6c6665479f-b6q8j:/# cd /usr/share/nginx/html/
root@k8spod2nfs-6c6665479f-b6q8j:/usr/share/nginx/html# ls
file.txt  index.html  index.html.1
root@k8spod2nfs-6c6665479f-b6q8j:/usr/share/nginx/html# echo hi >> index.html
root@k8spod2nfs-6c6665479f-b6q8j:/usr/share/nginx/html# cat index.html
hola
adios
hi
root@k8spod2nfs-6c6665479f-b6q8j:/usr/share/nginx/html# exit
MacBook-Pro:k8spod2nfs javiermugueta$ kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
k8spod2nfs   LoadBalancer   10.96.133.154   129.146.208.7   80:31728/TCP   8m
kubernetes   ClusterIP      10.96.0.1                 443/TCP        48m

Open a browser and put the public IP of the service:

Now get the public IP of the service created in Frankfurt, open a browser and see what happens:

It shows same content, awesome!!

And last, just in case you don’t trust, change again the content of index.html within a pod in the Frankfurt side:

MacBook-Pro:k8spod2nfs javiermugueta$ kubectl exec -it k8spod2nfs-6f48c6464f-2447d bash
root@k8spod2nfs-6f48c6464f-2447d:/# cd /usr/share/nginx/html/
root@k8spod2nfs-6f48c6464f-2447d:/usr/share/nginx/html# echo bye >> index.html

It seems is working fine, haha!!

That’s all folks! 🙂

Creating a Fast&Simple Container for Sending Messages to a Topic in Oracle Event Hub Cloud Service (aka OEHCS, which is a Kafka cluster) and Deploying it to Kubernetes Cluster


The container uses 4 environment variables, you can find a container already built for you here

SOURCE CODE OF THE PRODUCER

var sleep = require('system-sleep');

const oehcs_connect_url = process.env.OEHCS_CONNECTURL

const topic_name = process.env.TOPIC_NAME

const num_partitions = process.env.NUM_PARTITIONS

const message = process.env.MESSAGE

var kafka = require('kafka-node'),

HighLevelProducer = kafka.HighLevelProducer,

client = new kafka.KafkaClient({kafkaHost: oehcs_connect_url}),

producer = new HighLevelProducer(client);

var i = 0;

while (i >= 0 ){

var payloads = [{ topic: topic_name, messages: message , partition: i}];

//producer.on('ready', function () {

producer.send(payloads, function (err, data) {

console.log(data);

});

// });

i = i + 1;

if (i > num_partitions -1){

i = 0;

sleep( 1 );

}

}

THE DOCKERFILE

FROM oraclelinux:7-slim
WORKDIR /app
ADD . /app
RUN curl --silent --location https://rpm.nodesource.com/setup_10.x | bash -
RUN yum -y install nodejs npm
CMD ["node","producer-direct.js"]

THE YAML FOR K8S DEPLOYMENT

apiVersion: apps/v1

kind: Deployment

metadata:

name: oehcsnodeproducer-direct

labels:

app: oehcsnodeproducer-direct

spec:

replicas: 1

selector:

matchLabels:

app: oehcsnodeproducer-direct

strategy:

type: Recreate

template:

metadata:

labels:

app: oehcsnodeproducer-direct

spec:

containers:

- image: javiermugueta/oehcsnodeproducer-direct

env:

- name: OEHCS_CONNECTURL

value: "<ip1>:6667,<ip2>:6667,..."

- name: TOPIC_NAME

value: "R1"

- name: NUM_PARTITIONS

value: "10"

- name: MESSAGE

value: "{'put here what you want'}"

name: oehcsnodeproducer-direct

TEST IT AND SEE WHAT HAPPENS

Create the deployment and after 10 minutes take a look to production messages ratio:
kubectl apply -f my.yaml
oehcs-scale1.png
More or less 400/second…
Scale the deployment and take a look to new production ratios:
kubectl scale deployment oehcsnodeproducer-direct --replicas=2
Around 8000 messages/second!
Now add 9 partitions to the topic and take a look to new ratios:
add partitions
With 2 pods running and 10 partitions we are producing around 10K messages per second! As you can see partitioning improves performance!
10partitions.png
Let’s double the number of pods and see new ratios:
kubectl scale deployment oehcsnodeproducer-direct --replicas=4
And now 18K/second!
18k
That’s all folks!
Enjoy 😉

Creating a Java Microservice with Helidon/Microservice Archetype Deployed in Kubernetes


helidon

With Helidon you can create Java microservices easily. In this blog, we are creating/exposing a REST service that gets a JSON document stored in an Oracle database and retrieves it to the requestor. For retrieving the JSON document from the database we are using ORDS and SODA but you can use JDBC as well, we’ll show it shortly in another post.

First, let’s create the project with the available archetype:

mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=io.helidon.archetypes -DarchetypeArtifactId=helidon-quickstart-se -DarchetypeVersion=0.10.5 -DgroupId=io.helidon.examples -DartifactId=quickstart-se -Dpackage=io.helidon.examples.quickstart.se

Modify the GreetService class for calling a backend service and the MainTest class removing the tests, you can find how it looks like here on GitHub.

Package the app:

mvn clean package

Now, start the app

java -jar target/quickstart-se.jar

And test the app locally, the app starts listening in 0.0.0.0:8080:

http://localhost:8080/greet

Now, let’s containerize the app with the Dockerfile included in the project:

docker build -t quickstart-se target

Run the container and test again:

docker run --rm -p 8080:8080 quickstart-se:latest

http://localhost:8080/greet

Now let’s deploy to Kubernetes:

First, we tag the container and then push it to the registry:

docker tag quickstart-se javiermugueta/quickstart-se

docker push javiermugueta/quickstart-se

Now let’s modify the deployment yaml to create a LoadBalancer and for pulling the image previously pushed in the registry:

... 
labels:

app: ${project.artifactId}

spec:

type: LoadBalancer

selector:
...

spec:

containers:

- name: ${proje
ct.artifactId}

image: javiermugueta/quickstart-se

imagePullPolicy: IfNotPresent

ports:

...

 

Let’s deploy the app to k8s:
kubectl create -f target/app.yaml
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
quickstart-se LoadBalancer 10.96.56.43 1xy.x1.x5.x24 8080:32243/TCP 2m
Take note of the public IP and test again:
javamicroservice
That’s all folks!!
Enjoy;-)

Weblogic Kubernetes operator or how to run WebLogic​ clusters in k8s


There are lots of WebLogic clusters running around the globe every day. When you withdraw money in the ATM, buy lettuces in the supermarket or make a phone call there is a WebLogic server (and probably an Oracle database too) is executing some logic for you.

Computing paradigms today tend to new standards and Kubernetes seems to be a big player for running workloads that need scalability, high availability, fault tolerant and resilience to disasters.

WebLogic was born in the 2000s with concepts such clusters, managed servers or nodemanager. Those entities were engineered for building robust software designed to run in the infrastructure utilized in the last years.

With the advent of the cloud, new paradigms and technologies arise, but things can’t be constantly rebuilt every time a new technology appears because of the cost of renewing it. The number of lines of  Java code written and compiled to run in WebLogic out there is huge, so is good for you to have the confidence that your current software will keep running and will allow you to modernize your applications progressively. The importance of having providers that guarantee the continuity of businesses goes beyond the technology trends or the latest fashioned cool software product launched yesterday.

For that reason, Oracle provides WebLogic-Kubernetes-Operator, a collection of artifacts that transparently translates the WebLogic architectural design concepts (AdminServer, managed server, NodeManager, …) to the Kunernetes concepts (pods, deployments, persistent volumes, replicasets,…) allowing to run WebLogic topologies in k8s transparently.

domain-architecture

With WebLogic-Kubernetes-Operator, Oracle provides a way for keeping safe the investments you have done so far and gives you time to face the future with tranquility.

Enjoy 😉