How to Create Endpoints for external services in Kubernetes

The endpoints in kubernetes are the mechanism that directly interact and implement the Kubernetes Service

The Endpoints are underlying mechanism which are created in the background and enable us to talk to the kubernetes Services.
As we know that by creating a Kubernetes service we automatically generate the FQDN with the help of core-dns services

There was a requirement for me to setup the specific endpoint and create a service to convert a outside IP into the kubernetes FQDN [svc-name.namespace.cluster.local]
I managed to work around it by creating an endpoint of my external IP which was running mySQL.

[root@master01 ~]# cat Mysql-ep.yaml 
---
kind: Endpoints
apiVersion: v1
metadata:
 name: mysql-svc
 namespace: actoneye
subsets:
 - addresses:
     - ip: 172.22.110.130
   ports:
     - port: 3306

Lets take a look at Kubernetes Service yaml file.

[root@master01 ~]# cat Mysql-svc.yaml
---
kind: Service
apiVersion: v1
metadata:
 name: mysql-svc
spec:
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306

The mysql FQDN mysq-svc.dev.cluster.local was used in my application code for my cluster which the mysql resource was outside the kubernetes cluster.

Please try this out and let me know if you had any similar experiences to share.

Create a new kubernetes user with custom kubeconfig auth

The important directories in the reckoning are /etc/kubernetes/pki/
The file ca.key and ca.crt are the Certificate Authority key and certificate respectively.

STEP 1: Generating the key and .csr(Certificate Signing Request)

Lets now generate the .key and .csr. certificates for 1 year with openssl:

[root@node01 ssl]# openssl req -new -sha256 -newkey rsa:2048 -nodes -keyout builduser01.key -days 365 -out builduser01.csr -sha256 -subj "/C=IN/ST=TG/L=/O=/OU=/CN=/subjectAltName=DNS.1="

Verification of the CSR:

[root@node01 ssl]# openssl req -in linuxcent.com.csr -noout -text
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=IN, ST=TG/subjectAltName=DNS.1= -- INFORMATION RETRACTED --
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:00:e4:b4:24:d7:22:ec:5d:c1:37:8c:d1:a0:62:17:
96:24:77:8d:75:4e:d5:74:15:4d:61:e0:8b:66:d6:
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         87:ef:83:b2:a6:f5:3a:f3:6f:1c:e4:02:ec:bf:5d:75:64:1d:

STEP 2: Digitally Signing .csr and generating .crt using root CA files.

Now we will using the root ca.key and ca.crt to digitally sign this csr and generate a .crt

[root@node01 ssl]# openssl x509 -req -in builduser01.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out builduser01.crt -days 365 -sha256
Signature ok
subject=/C=IN/ST=TG/subjectAltName=DNS.1=
Getting CA Private Key

We have successfully generated the .crt file from the .csr along with the .key file from STEP1 with the below names. builduser01.crt and builduser01.key

How to create user accounts on kubernetes

We now will create a builduser-config to create a kubeconfig for new user.

Injecting the cluster and the API server information into the kubernetes config file:

[root@node01 ssl]# kubectl config --kubeconfig=builduser-config set-cluster kubernetes --server=https://10.100.0.10:6443 --insecure-skip-tls-verify

We are now injecting the CA certificate information into the config file:

[root@node01 ssl]# kubectl config --kubeconfig=builduser-config set-cluster kubernetes --server=https://10.100.0.10:6443 --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true

Injecting the credentials key and cert file data into the config file.

[root@node01 ssl]# kubectl config --kubeconfig=builduser-config set-credentials builduser01 --client-certificate=linuxcent.com.crt --client-key=linuxcent.com.key --embed-certs=true

Using –embed-certs=true, we can dump the cert and key file data into the config file instead of writing the path names

[root@node01 ssl]# kubectl config --kubeconfig=builduser-config set-credentials builduser01 --username=builduser01 --password=password123

Using the username and password is not explicitly required while the keys are being used.
Now copy the builduser-config to the $HOME/.kube/config and connect to the kubernetes cluster.

kubernetes bash completion

Wouldn’t it be great when we are using kubernetes and just tab to get a list of possible subcommands?

We have the extended facility to automatically tab and get the kubectl command suggestions, This feature is inbuilt into the kubectl and kubeadmin, All we need to just extract the script and enable it to the .bash_profile and source it. Lets do it as show below

[vamshi@workstation ~]$ kubectl completion bash > ~/.kube/k8s_bash_completion.sh
[vamshi@workstation ~]$ echo -e "\n#kubectl shell completion\nsource '$HOME/.kube/k8s_bash_completion.sh'\n" >> $HOME/.bash_profile
[vamshi@workstation ~]$ source $HOME/.bash_profile

Once you have successfully sourced the .bash_profie file.. type kubectl commands and keep tabbing all the way to get the suitable suggestions.

Kubernetes installation on Centos

Kubernetes is a Orchestration mechanism for running your container infrastructure on linux based machines.
In this tutorial we will be looking at the server based kubernetes installation on centos7 linux server OS.

Installing the kubernetes minimum requirements

Have 2 CPU cores with 2 GB or more RAM.

Have the swap memory disabled.

The swap memory can be disabled using the swapoff -a command.

Now, Lets take a look at the prerequisites to perform a kubernetes installation:

The Docker as the runtime container engine.
We make sure that the docker is already installed on the system.

[root@node01 ~]# docker --version
Docker version 1.13.1, build b2f74b2/1.13.1

Ensure you are loggedin as the root user to the machine to perform the remaining procedure.
We now start of the Kubernetes installation by adding the yum repo as demonstrated below:

STEP 1:

[root@node01 ~]# cat <<EOF > /etc/yum.repos.d/kubernetes.repo
> [kubernetes]
> name=Kubernetes
> baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
> enabled=1
> gpgcheck=1
> repo_gpgcheck=1
> gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
> EOF

Now update the repositories with yum update command:

# yum update
-- OUTPUT TRUNCATED --
kubernetes/signature                                                                                                                             |  454 B  00:00:00     
Retrieving key from https://packages.cloud.google.com/yum/doc/yum-key.gpg
Importing GPG key 0xA7317B0F:
 Userid     : "Google Cloud Packages Automatic Signing Key <gc-team@google.com>"
 Fingerprint: d0bc 747f d8ca f711 7500 d6fa 3746 c208 a731 7b0f
 From       : https://packages.cloud.google.com/yum/doc/yum-key.gpg
Is this ok [y/N]: y
Retrieving key from https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
-- OUTPUT TRUNCATED --

Till this step the repository addition is complete.

STEP2:

We now Hop onto the proposed Kubernetes master server, proceed with setup of the kubenetes master and Container cluster management components..
Downloading the kubernetes master and the kubernetes network interface binaries to configure the kubernetes master.
The yum package manager offer the following components which have to installed as dependencies to configure the kubernetes-master.

We should do some configuration before hand to enable the bridging net.bridge.bridge-nf-call-iptables

Enabling the bridging on the master node by adding the following to /etc/sysctl.d/kubernetes.conf. Create this file under /etc/sysctl.d

[root@node01 ~]# cat /etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

Or else we might run into errors like the one as follows:

[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1

Now run the below command to read the new bridging rules.

# sysctl --system

Disabling SELINUX on the kubernetes master

We need to ensure the selinux is disabled for the purpose of simplifying the installation, You may encounter many cases where the selinux context obstructing the kublet to send the information to the kube-controller and kube-scheuler

[vamshi@node01 ~]$ sudo setenforce 0

Setting it to 0 using setenforce will set the selinux to permissive mode, and Verify it with the getenforce will display the results.

[vamshi@node01 ~]$ sudo getenforce 
Permissive

To make the SELINUX rules persistent across the reboot you need to modify its configuration file

[root@node01 ~]# sed -i 's/SELINUX=enabled/SELINUX=disabled/' /etc/selinux/config 
[root@node01 ~]# cat /etc/selinux/config 

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

STEP3

Now lets shift our focus onto the Kubernetes and see the following core components of Kubernetes:

  • kube-apiserver
  • kube-controller-manager
  • kube-scheduler
  • kubelet
  • kube-proxy

 

We shall now beign installing kubeadm and kubernetes-cni

# yum install kubeadm kubernetes-cni

Here we have marked the kubernetes-cni because of the network components which goes along well with the kubernetes network scope management.

The important component is kubeadm which presides over the kubernetes cluster initialization.
To access the kubernetes we need the we need to install the kubectl, Although It will installed along with kubernetes-client package and if required can be install with the following command:

# yum install kubectl

 

STEP 4: Your Kubernetes worker Node

This is exclusive for the worker nodes which will be connected to the working kubernetes master.
STEP 1 is required to setup on the worker node so we can install and configure the kubernetes-node binary.
We will download the kubernetes-node Binaries from the yum package manager.

# yum install kubernetes-node kubernetes-client

STEP 5: Enabling the Full potential on the control-plane

The important step to enable and start the core kubernetes master services.
Here are the core important kubernetes services in the control-plane.

 kube-apiserver
 kube-controller-manager
 kube-scheduler

The Below services contributes on the data-plane or the worker-nodes and are also important on the contol-plane

 kubelet
 kube-proxy

The important configuration files on the kubernetes master:

  • /etc/kubernetes/manifests
  • /etc/kubernetes/pki

The important config files are:

  • /etc/kubernetes/admin.conf
  • /etc/kubernetes/kubelet.conf
  • /etc/kubernetes/bootstrap-kubelet.conf
  • /etc/kubernetes/controller-manager.conf
  • /etc/kubernetes/scheduler.conf

The stateful data directories in Kubernetes are as below:

  • /var/lib/etcd
  • /var/lib/kubelet
  • /var/lib/dockershim
  • /var/run/kubernetes
  • /var/lib/cni

 

Now we initialize the kubernetes with kubeadm as we see as follows:

kubeadm init --apiserver-advertise-address [preferred-master-node-ip-address|FQDN]

With the kubernetes successfully configured as follows you can begin digging deep onto the setup.

[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 10.100.0.10:6443 --token 123jei.123456783n6o8bq \
    --discovery-token-ca-cert-hash sha256:12345678906bff25a6d132a539e87321833181

Upon the successful installation you should see the following information with the client and the server version information:

Copy the kubeconfig file from the path /etc/kubernetes/config to the desired home directory under .kube/config

[root@node01 ~]# kubectl version
Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.1", GitCommit:"4485c6f18cee9a5d3c3b4e523bd27972b1b53892", GitTreeState:"clean", BuildDate:"2019-07-18T09:18:22Z", GoVersion:"go1.12.5", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.0", GitCommit:"e8462b5b5dc2584fdcd18e6bcfe9f1e4d970a529", GitTreeState:"clean", BuildDate:"2019-06-19T16:32:14Z", GoVersion:"go1.12.5", Compiler:"gc", Platform:"linux/amd64"}

STEP 6: Initialize the Networking in Kubernetes

Here we enable the kubernetes networking with the preferred network provider:

kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calico.yaml

We should be able to get the nodes

[root@node01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master.linuxcent.com Ready master 3h7m v1.18.2

Common Errors during the setup:

There can be some common errors during the installation I have faced and able to reproduce them in-order to find a quick resolution.

The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)
[E0509 9645 kubelet_node_status.go:92] Unable to register node

If you encounter the above error, then please ensure the following things:
Ensure that you have the kubelet service running,
The selinux is in disabled state. and then reinitialize, kubeadm reset and then kubeadm init command.

There may be errors related to the DNS not functioning:

Warning  FailedScheduling    default-scheduler  0/1 nodes are available: 1 node(s) had taint {node.kubernetes.io/not-ready: }, that the pod didn't tolerate.
runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

Then it definetly needs to apply the kubernetes networking plugin, please choose the calico or Weavenet or your preferred network plugin and apply those components.

Setup and configure Zookeper and Kafka on Linux

We would need java runtime environment to install and operate the kafka and zookeeper programs on our linux environment as a dependency which uses the java runtime environment.
So lets quickly check the current java version on the system with java -version.
If its not present Lets now begin with the setup of Java and quickly download the java stable version from the epel repository.

# yum install java-1.8.0-openjdk

Once the java version is installed we verify it with the java -version command.
Creating the kafka user account.

# useradd kafka -m -d /opt/kafka

Adding the kafka password

# echo "kafka" | passwd kafka --stdin
usermod -aG wheel kafka
# su -l kafka

Now login to the system as kafka user.

# cd /opt

Navigate to the url : https://downloads.apache.org/kafka/ and download the latest kafka version

# curl https://downloads.apache.org/kafka/2.5.0/kafka_2.13-2.5.0.tgz -o /opt/kafka.tgz
# tar -xvzf ~/opt/kafka.tgz --strip 1
# cd /opt/kafka
# cp -a /opt/kafka/config/server.properties ~/opt/kafka/config/server.properties.bkp
# echo -e "\ndelete.topic.enable = true\nauto.create.topics.enable = true" >> /opt/kafka/config/server.properties

Adding the Kafka start/stop scripts to systemctl controller daemon services

# sudo vim /etc/systemd/system/zookeeper.service
Add the following lines to /etc/systemd/system/zookeeper.service
[Unit]
Requires=network.target remote-fs.target
After=network.target remote-fs.target

[Service]
Type=simple
User=kafka
ExecStart=/opt/kafka/bin/zookeeper-server-start.sh /opt/kafka/config/zookeeper.properties
ExecStop=/opt/kafka/bin/zookeeper-server-stop.sh
Restart=on-abnormal

[Install]
WantedBy=multi-user.target

Now adding the Kafka control scripts to systemd service

# sudo vim /etc/systemd/system/kafka.service
Add the following lines to /etc/systemd/system/kafka.service
[Unit]
Requires=zookeeper.service
After=zookeeper.service

[Service]
Type=simple
User=kafka
ExecStart=/bin/sh -c '/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties > /opt/kafka/kafka.log 2>&1'
ExecStop=/opt/kafka/bin/kafka-server-stop.sh
Restart=on-abnormal

[Install]
WantedBy=multi-user.target
# sudo chown kafka.kafka -R /opt/kafka/logs
# sudo mkdir /var/log/kafka-logs
# sudo chown kafka.kafka -R /var/log/kafka-logs

Now start the zookeeper and kafka services as follows:

# sudo systemctl enable zookeeper --now

# sudo systemctl enable kafka --now





Install java on Linux centos

In this tutorial we will quickly setup java on linux centos,

We will be using the yum command to download the openjdk 1.8 and install

[vamshi@node01 ~]$ sudo yum install java-1.8.0-openjdk.x86_64

We have installed the java openjdk 1.8 and we can check the version using java -version

[vamshi@node01 ~]$ java -version
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)

 

We make use of the alternatives command in centos which lists if we have any other version of java installed on the machine, and then enabling the default java version on the system wide.

[vamshi@node01 ~]$ alternatives --list | grep java
java auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre/bin/java
jre_openjdk auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre
jre_1.8.0 auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre
jre_1.7.0 auto /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.261-2.6.22.2.el7_8.x86_64/jre
[vamshi@node01 ~]$ sudo alternatives --config java

There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
*  1           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre/bin/java)
 + 2           java-1.7.0-openjdk.x86_64 (/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.261-2.6.22.2.el7_8.x86_64/jre/bin/java)

Enter to keep the current selection[+], or type selection number: 1

This enabled openjdk1.8 to be the default version of java.

Setting JAVA_HOME path
In order to set the system JAVA_HOME path on the system we need to export this variable, for the obvious reasons of other programs and users using the classpath such as while using maven or a servlet container.

Now there are two levels we can setup the visibility of JAVA_HOME environment variable.
1. Setup JAVA_HOME for single user profile
We need to update the changes to the ~/.bash_profile

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre/bin/

PATH=$PATH:$JAVA_HOME

export PATH

Now we need enforce the changes with reloading the .bash_profile with a simple logout and then login into the system or we can source the file ~/.bash_profile as follows:

[vamshi@node01 ~]$ source .bash_profile

Verifying the changes:

[vamshi@node01 ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/vamshi/.local/bin:/home/vamshi/bin:/home/vamshi/.local/bin:/home/vamshi/bin:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre/bin/

2. Setup JAVA_HOME for the system wide profile and available to all the users.

[vamshi@node01 ~]$ sudo sh -c "echo -e 'export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre/bin/' > /etc/profile.d/java.sh"

This echo command writes the JAVA_HOME path to the system profile.d and creates a file java.sh which is read system wide level.

Ensure the changes are written to /etc/profile.d/java.sh

[vamshi@node01 ~]$ cat /etc/profile.d/java.sh
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre/bin/

Now source to apply the changes immediately to the file /etc/profile.d/java.sh as follows

[vamshi@node01 ~]$ sudo sh -c ' source /etc/profile.d/java.sh '

Or login to the root account and run the source command

Ensure to run the env command

[vamshi@node01 ~]$ env  | grep JAVA_HOME
JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre/bin/

sed – The Stream editor in Linux

The Stream Editor(sed) is a text manipulation program, that takes the input from stdin and from the text files, It writes to the stdout and modifies the input files accordingly. The text manipulation means deleting characters and words; Inserting text into the source file on the fly.
This is a transformation operation and quiet a handy skill to have for someone working in linux shell.

The sed comprises of two operations, The first one is a regex search and match operation and the second one is replace operation accordingly. This combines the greater power of search and replace of text from stdin and from the flat files.
Here is general syntax of sed command is:

# sed [-n] -e 'options/commands' files
# sed [-n] -f sed-scriptfile
# sed -i filename -e 'options/commands'

-e is the edit option used on the cli.
-f to take the sed commands from the scriptfile
-n or –quiet option supresses the output unless specified with -p or -s

We will look at some of the notable options the sed offers.

Some practical usecases, But before that we take at our sample README.txt.

Substitute and Replace with sed:

sed command offers the -s option which is exclusive for search and replace operation also known as search and substitution.

[vamshi@node02 sed]$ echo Welcome to LinuxCent | sed -e 's/e/E/'
WElcome to LinuxCent

This replaces the e to E in the input received and prints to stdout.
We can apply the same to the Text file and achieve the same results.

[vamshi@node02 ~]$ sed -e 's|u|U|' README.txt
centos 	
debian 	
redhat 	
Ubuntu

But the important thins to be noted is that the first occurring pattern match per line is only replaced. In out case only 1 letter per line as the letter u is replaced in ubuntu by U.

Substitute and replace globally using the option -g.

We run the below command stdin input stream as show below:

[vamshi@node02 sed]$ echo Welcome to LinuxCent | sed -e 's/e/E/g'
WElcomE to LinuxCEnt

Running the global option g on the fileinput as shown below.

[vamshi@node02 ~]$ sed -e 's/u/U/g' README.txt
centos 
debian 	
redhat 	
UbUntU 	

Substitute the later occurrences using sed. We search for the 3rd occurrence of letter u and if matched replace it with U.

[vamshi@node02 ~]$ sed -e 's/u/U/3g' README.txt
centos 	
debian 	
redhat 	
ubuntU

In the above case we have seen the lowercase u has been replaced with Uppercase U at the third occurrence.
Now let us append the word to the end of the each line using the below syntax:

[vamshi@node02 ~]$ sed -e 's/$/ Linux/' README.txt
centos Linux
debian Linux
redhat Linux
ubuntu Linux

Adding text to the file data at the beginning of each line and writing to the stdout.

[vamshi@node02 Linux-blog]$ sed -e 's/^/Distro name: /' Distronames.txt 
Distro name: centos Linux
Distro name: debian Linux
Distro name: redhat Linux
Distro name: ubuntu Linux

sed Interactive Editor: How to write the modified sed data into the same text file?

We can use the -i Interactive Editor option in combination with most other sed options, the input file content is directly modified according to the command pattern.
Example Given.

[vamshi@node02 sed]$ sed -e 's/e/E/g' -i intro.txt
[vamshi@node02 sed]$ cat intro.txt
WElcomE to LinuxCEnt

We use the -i option to append some text to a file as demonstrated as follows:

[vamshi@node02 Linux-blog]$ sed -i 's/$/ Linux/' README.txt
[vamshi@node02 Linux-blog]$ cat README.txt 
centos Linux
debian Linux
redhat Linux
ubuntu Linux

Here we append the words Linux to end of the each line
Alternate to -i you can also use the output redirection to write to a new fileĀ  as shown below.

[vamshi@node02 ~]$ sed -e 's/$/ Linux/' README.txt > OSnames.txt

Delete Operations with sed

Delete all the lines containing the pattern:

[vamshi@node02 ~]$ sed -e /ubu/d README.txt
centos Linux 
debian Linux 
redhat Linux

Here we matched the word ubuntu and hence have deleted that line from output.

We can use the ! inverse operator with the delete, demonstrated as follows:

[vamshi@node02 Linux-blog]$ sed -e '/ubu/!d' Distronames.txt
ubuntu Linux

Using the Ranges in sed

Extracting only the specific /BEGIN and /END pattern using sed.

[vamshi@node02 Linux-blog]$ cat Distronames.txt | sed -n -e '/^centos/,/^debian/p'
centos Linux	
debian Linux

Substitution of Range of lines

[vamshi@node02 Linux-blog]$ sed -e  '1,3s/u/U/' Distronames.txt
centos LinUx.	
debian LinUx.	
redhat LinUx.	
ubuntu Linux.

Delete the . at the end of each line

[vamshi@node02 Linux-blog]$ sed -e 's/.$//' Distronames.txt

Print only the lines containing the word “hat”

[vamshi@node02 Linux-blog]$ sed -n -e '/hat/p' Distronames.txt 
redhat Linux

Use sed to Match the pattern insert text.
Insert the lines before the matched pattern in file

[vamshi@node02 Linux-blog]$ cat README.txt | sed -e '/centos/i\Distro Names '
Distro Names 
centos
debian
redhat
ubuntu

The above scenario we have inserted the sentence “Distro Names” before the occurrence of the work centos.

[vamshi@node02 Linux-blog]$ cat Distronames.txt | sed -e '1a\------------'
Distro Names 
------------
centos
debian
redhat
ubuntu

The ———— are appended to the text after the 1st line

How to push a docker image to a private repository

How to push a docker image to a private repository: In this tutorial we will cover the the stages dealing with tagging the image and pushing a docker image to the private repository.

For Docker login please refer Docker login to private registry

Now we need to see the two types of docker registry references when pushing the docker images, lets look at the standard docker registry references.

docker image registry reference types

Public registry format:

The public registry is a free to signup and start using immediately. Here is the docker tagging format.

[docker-hub-username]/[image-name]:[tag]

Private registry format:
The private registry is setup on-premises using a hosted docker registry software like docker-registry, nexus-docker registry are among are some of the popular tools to be named. The software is available over the connected network with the given server-name and the desired port to connect to the docker registry service. The format of it is as below

docker-registry-host:docker-registry-port/[user-name/]image-name[:tag]

 

STEP 1: Tagging a docker image

Tagging is a crucial part, As the docker image will be pre-fixed with the registry name which forms the complete unique docker image identity. [DOCKER-REGISTRY-NAME]/[DOCKER-IMAGE]:[TAG]

Eg of Public registry format:

# docker-repo/nginx:latest.

So that it registry name is be pushed to the prefixed Repository name, and Hence the docker image needs to be properly tagged.

The information about your current docker login repository can be found with docker info command.

The docker image has to be properly tagged with docker tag command and prefixed with the Docker-repository name as follows:

[root@docker03:~]#  sudo docker tag nginx:v1 nexusreg.linuxcent.com:5000/nginx:v1

the Image gets tagged with the relevant registry name with docker tag command:

[root@docker03:~]#  docker images
REPOSITORY                                       TAG                 IMAGE ID            CREATED             SIZE
docker.io/nginx                                  latest              602e111c06b6        2 weeks ago         127 MB
nexusreg.linuxcent.com:5000/nginx                v1                  0bc8c50014c7        20 minutes ago      193 MB
jfrog.linuxcent.com/debian-vamshi                v1                  0568d1ef9d81        1 day ago           253 MB

STEP 2: Push the image to a Private Docker registry

The docker push offers the user the capability to upload the docker image on disk to be shared onto a remote docker registry / repository with username authorization.

The process to docker push to private repository is a simple command and takes the following syntax:

[root@docker03:~]#  docker push [DOCKER-REGISTRY-NAME]/[DOCKER-IMAGE]:[TAG]

This will now enable docker image to be pushed to the destined repository.

The syntax command to push the docker image to the destination repository.
Example given:

[root@docker03:~]#  docker push nexusreg.linuxcent.com:5000/nginx:v1

 

How to allocate resources to docker images in Runtime?

We have seen the docker runtime environment takes up the overall available system resources on the system and tends to impact the base system.

To better utilize the containers, we can avail the resource cap and define the metric limits on specific containers while starting up the respective docker images..

The general syntax goes as follows:

# docker run --cpus ="x.x" --memory=x[M|G] docker-image

Here we see the demonstration

[root@node01 ~]# docker run --cpus="0.2" --memory="200M" jenkins:latest
/usr/bin/docker-current: Error response from daemon: Minimum memory limit allowed is 4MB.

It should be noticed that the minimum Memory limit allowed for the docker container to run is 4MB and the minimum CPU cores is at 0.01, any thing lower that this means the container runtime fails to allocate sufficient resources. These limits will be efficient when running on some test and debug scenarios.

How to login and connect to docker container tty with a username

How to login to the docker through commandline?

The docker exec is similar to running a tty on a linux machine. the only difference is it can accept many more exec connections, Although you can enable ssh to the docker but it will only be possible while running an openssh server inside the running container.

You can exec to connect to a running container much like the ssh into the running machine, Here we use the special options -i or --interactive to provide interaction and -t or --tty which allocates a pseudo tty terminal of the type of shell that is followed
The syntax of docker exec is as below:

docker exec -it <container-id | container-name> bash
[vamshi@node01 ~]$ docker exec -it b511234ebe31 bash
jenkins@b511234ebe31:/$ id
uid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins)

We know that the docker exec command is used opens up a tty terminal to connect to the running docker container, but It will connect us with the Default USER that was activated during it docker build.

We can use the [/code]-u[/code] flag to connect to the container with the username that is enabled for that image, We see the below example

[vamshi@node01 ~]# docker exec -it  -u root b511234ebe31 bash
root@b511234ebe31:/# pwd
/
root@b511234ebe31:/# id
uid=0(root) gid=0(root) groups=0(root)

 

 

Docker Monitoring with top and stats

The docker provides some in-house monitoring tools to extract the runtime information.

docker top is one such command.

[root@node01 ~]# docker top [container-id | container-name]

Here is the output of the docker top command.

[root@node01 ~]# docker top admiring_torvalds 
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
centos              13169               13153               0                   10:43               ?                   00:00:00            /bin/tini -- /usr/local/bin/jenkins.sh
centos              13191               13169               9                   10:43               ?                   00:00:21            java -jar /usr/share/jenkins/jenkins.war

When you try to see the stats of an exited container it shows up with an error as follows as the container is not running

[vamshi@node01 ~]$ docker top exited_container
Error response from daemon: Container 31b8ab84a175ce79b03ba1c9608e9d358db45f74914407212b0d2c7744324806 is not running

The docker also provides a stat command which prints out the current docker image stats
The syntax:
# sudo docker stats [CONTAINER ID | CONTAINER NAME]

This is demonstrated as follows:

CONTAINER ID        NAME                   CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
73caf780c813        do-nothing-container   0.00%               996KiB / 471.5MiB   0.21%               2.08kB / 0B         4.81MB / 0B         1