Docker: Quickstart

OS: CentOS 7

lets create a docker yum repo.

# cd /etc/yum.repos.d/
# vim docker.repo
[dockerrepo]
name= Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg

###save & exit

# yum update
# yum install docker-engine -y

### in EL 6 disabled SELINUX or add chcon

# systemctl enable docker
# systemctl start docker
# docker --version
# docker images
# cd /var/run/
# ls -al dock*
# usermod -a -G docker user
# cat /etc/group | grep docker -. as username : user
### relogin with username as user and try again
# docker images -. as username : user


$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$ BASE IMAGES $$$$$$$$$$
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

[as username: user]

$ docker images
$ docker search centos
$ docker search apache
$ docker search httpd

- pull images from docker hub
$ docker pull
$ docker pull hello-world
$ docker images

- run docker images
$ docker run hello-world
### base images can be referred by repositiry name and image ID.

$ docker pull centos:centos6
$ docker pull centos #[same]
$ docker pull centos:latest #[same]

### centos6 is the version tag and if you leave it empty what is the latest available according to hub will be pulled.

$ docker images

- to know more about an downloaded image you can use docker inspect

$ docker inspect nginx
$ docker inspect centos
$ docker inspect hello-world

$ docker images
$ docker pull docker/whalesay

- run a docker images
$ docker run docker/whalesay cowsay hello
$ docker run docker/whalesay cownsay MyIGT
### If a image not available locally, then docker will check at docker hub and doownload it from there if its available.

- check running docker process
$ docker ps

- chek docker process history
$ docker ps -a

### To run docker image we need a container and each container have an image loaded into it and while container running an image it will have a unique contaner ID.

- inspect a container
$ docker inspect

### exited process of container inspect will not contain much information but running process of a container can provide you more detail.

### by default docker networking will be from 172.17.0.2 to 172.17.0.254.

### if you want to run a container in interactive mode and in terminal mode then use -it flag to docker run command.

$ docker run -it
$ docker run -it centos:latest /bin/bash

-. try running few commandsa here

-. try opening another terminal and observer the output of

$ docker ps

and exit from the containers with

$ exit

and observer the o/p of

$ docker ps
$ docker ps -a


### if you want to run the docker container not in interactive,terminal mode but detached mode then you flag 'd'

$ docker run -d  
$ docker run -d centos:latest /bin/bash

### here conainers start the docker image and execute the /bin/bash command and then exit.

$ docker run -d nginx:latest

### now nginx run continously running in the backgroun. confirm with

$ docker ps

and to find more information like ip address about this running container use

$ docker inspect

Note: to understand better save the output of inspect while docker running and stopped anc compare the output

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
[user@rgenupula4 tmp]$ diff naughty_leakey.txt naughty_leakey_off.txt
8,9c8,9
<             "Status": "running",
<             "Running": true,
---
>             "Status": "exited",
>             "Running": false,
14c14
<             "Pid": 2289,
---
>             "Pid": 0,
18c18
<             "FinishedAt": "0001-01-01T00:00:00Z"
---
>             "FinishedAt": "2017-09-24T07:27:33.032213142Z"
153,154c153,154
<             "EndpointID": "c9bd0bd670a302e23b704380d4f24507d022bb2da80b074c7ed3204b2c54befe",
<             "Gateway": "172.17.0.1",
---
>             "EndpointID": "",
>             "Gateway": "",
157,158c157,158
<             "IPAddress": "172.17.0.2",
<             "IPPrefixLen": 16,
---
>             "IPAddress": "",
>             "IPPrefixLen": 0,
160c160
<             "MacAddress": "02:42:ac:11:00:02",
---
>             "MacAddress": "",
167,170c167,170
<                     "EndpointID": "c9bd0bd670a302e23b704380d4f24507d022bb2da80b074c7ed3204b2c54befe",
<                     "Gateway": "172.17.0.1",
<                     "IPAddress": "172.17.0.2",
<                     "IPPrefixLen": 16,
---
>                     "EndpointID": "",
>                     "Gateway": "",
>                     "IPAddress": "",
>                     "IPPrefixLen": 0,
174c174
<                     "MacAddress": "02:42:ac:11:00:02"
---
>                     "MacAddress": ""

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
Now
$ docker ps

### it will give ports information about the running iamge. You will be able to access those ports.

-. dowload elinks in the host machine

and $ elinks https://

### stop the container

$ docker stop  

### we can give custom name to container reference

$ docker run -d --name=myWeb01 nginx:latest

### observer output of
$ docker ps

### inspection
$ docker inspect myWeb01

## start another
$ docker run -d --name=myWeb02 nginx:latest

### observer
$ docker ps

### inspect
$ docker inspect myWeb01
$ docker inspect myWeb02

### stop them
$ docker stop myWeb01
$ docker stop myWeb02

-. you can stop multiple docker instances with

$ docker stop myWeb01 myWeb02 myWeb03

-. docker can be attached if detached with attach string to docker command

$ docker images
$ docker ps
$ docker -d --name=web04 nginx:latest
$ docker attach web04
$ docker stop web04
$ docker start web04

### we can also execute a particluar command in a container and we are done with the command we can still exit from the command but can keep container running in the background and this is feasible with docker exec command. For example start a docker container with

$ docker exec /bin/bash LifeCycle1
$ docker ps
$ docker exec -it LifeCycle1 /bin/bash

.- try some commands
$ exit

### and then check output again with
$ docker ps
$ docker ps -a

### you can stop a container with either "container ID" or "Container Name"

$ docker stop LifeCycle1

### you can restart a container with

$ docker restart LifeCycle1

### observe

$ docker ps


$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$ IMAGE $$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$ AND CONTAINER MANAGEMENT $$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

### Remove an docker image

$ docker rmi centos:centos6

### force remove

$ docker rmi -f centos:centos6

### If you have an image centos:centos6 and if we start another container with image name i.e docker run then docker image centos:centos6 will have a reference dependent id on this new container id. so if you want to remove the docker image then we must remove the container image and then remove that docker image.

$ docker ps -a

### find the image reference

$ docker rm

### find the reference ID's of all the docker containers

$ docker ps -a -q

### remove all docker containers

$ docker rm $(docker ps -a -q)

### Assume you have started a container and stopped. And then you force removed the image used for the contianer. Now you  still will be able to start/run the container. because whe you start a new container actually docker image will be full cloned into that continer. so even though docker container can start even though image got removed.

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$$$$$$ Redirection - Ports & Volumes $$$$$$$$$$
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

# find the images
$ docker images

# run the container
$ docker run -d --name=myWeb06 nginx:latest

# observe docker ps
$ docker ps

# insepct the container
$ docker inspect myWeb06

# get ip address of a running container
$ docker inspect myWeb06 | grep IPAddr

# verify nginx
$ elinks https://

### we can expose docker ports to local ports. With -P flag we can tell OS that any ports used by below docker container can have a random port35000 to 60000 range
$ docker run -d --name=myWeb07 -P nginx:latest

# observe the output
$ docker ps

### try elinks as well for both docker ports and exposed external ports. And these ports can be extracted with

$ docker inspect | grep IPAddr
$ docker ps
$ docker port $CONTAINERPORT

### we can assign to explicit port numbers instead of random port numbers

$ docker run -d -p 8080:80 --name=myWeb09 nginx:latest

-> 8080: Localhost port
-> 80: Port inside the docker

### instead of mounting docker containers at default location /var/lib/docker we can mount docker in any custom loation we want with -v flag

$ docker run -d -p 8080:80 --name=myWeb11 -v /mnt/data nginx:latest

### we can mount a local storage volume remotely

-> make sure where you are in your server and write a sample html file

$ vim index.html




This is genupulas nginx server


save and close.

Lets say this file is located at current working directory/www/index.html


$ docker run -d -p 8080:80 --name=myWeb12 -v /home/user/www:/usr/share/nginx/html nginx:latest

$ docker ps

$ elinks http://localhost:8080

# you would be able to see the file you have created.

$ vim index.html




This is genupulas nginx server

new line has been added




save and exit.

$ elinks http://localhost:8080

And you will see the changes you have made.


###############################################################################
#######################        DOCKER FILE ###################################
###############################################################################


$ vim Dockerfile
# where is the image coming from ?
FROM debian:stable
MAINTAINER rajagenupula

# run the commands with RUN flag
RUN apt-get update
RUN apt-get upgrade

save & exit for now.

$ docker build -t rajagenupula/myapache .

$ vim Docker file

# wher eis the image located
FROM debian:latest
MAINTAINER rajagenupula

# run few commands in the docker image
RUN apt-get update
RUN apt-get upgrade
RUN apt-get install telnet

save & exit.

$ docker build -t rajagenupula/myapache .

### Every run creates a new layer and any failed run will not add any layer. And that image is incomplete. So Better to remove that image and correct your docker file and try again.

$ vim Dockerfile
# from where
FROM debian:latest
MAINTAINER rajagenupula

# run commands
RUN apt-get update && apt-get install apache2 openssh-server telnet elinks

save & exit.

Advantage with this is total run will stay in one container layer and it will save disk space.

#### lets add environment variables
$ vim Dockerfile
# where
FROM debian:latest
MAINTAINER rajagenupula


# run
RUN apt-get update && apt-get install openssh-server apache2 elinks openssh-server

# Environment variables

ENV MYVALUE my-value

save & exit.

$ docker build -t rajagenupula/myapache .

##### Lets expose ports

$ vim Dockerfile

FROM debain:latest
MAINTAINER rajagenupula

RUN apt-get update && apt-get install openssh-server apache2 telnet elinks

ENV MYVALUE my-value

EXPOSE 80
EXPOSE 22

save & exit.

$ docker build -t latest123/myapache .

# observe port expose
$ docker ps

### Execute commands

$ vim Dockerfile

FROM debian:stable
MAINTAINER rajagenupula
RUN apt-get update && apt-get install openssh-server telnet apache2 elinks
ENV MY_VALUE myval
EXPOSE 80
CMD ["/usr/sbin/apache2ctl","-D","FOREGROUND"]

save & exit.

# observe
$ docker ps

# elinks
$ docker inspect | grep IPAddr
$ elinks http://

# connecting
$ docker exec -it /bin/bash

# check apache
$ ps -ef | grep apache

# check env
$ echo $MYVALUE

# exit
$ exit

Note: as initiated with "exec" even we exit still contianer runs in the background.

Note: Practice : expose ports between localhost and docker host and mount volume as well.



















BASH: Extract only IP Address from ip addr command

Hello ,

You can use below shell script to extract only IP address from ip command.

Command :  ip addr show  | grep -oP 'inet \K[^/]+'

Example:

[root@server cgi-bin]# ip addr show  | grep -oP 'inet \K[^/]+'
127.0.0.1
10.0.2.15
192.168.56.102


Note: If you are trying to use ip command in cron jobs, please use as /sbin/ip 



Hope it helps  you. 

Fix: Command not found for whois and dig

Hello,

If you have not installed bind-utils then you wont be able to execute dig commands. basically dig command can be used to DNS information and reverse lookup of a host etc.

To install dig commands , type below commands in your terminal

yum install bind-utils

Then you can try with

dig google.com
dig -x google.com 

If you have executed those commands, you will see sample output as below


and if who is command not working then you have to install jwhois package.

yum install jwhois
and you can test command usage with

whois google.com


Hope it helps you some day!!!!!!!!!!!!!!







Root CA and Wildcard Certificate Generation in CentOS/RHEL 6&7

     Hi folks ! this is one of the best method to create your own RootCA server and generating self-signed wildcard certificates.The greatest advantage of following this method: this would not make any system level changes, as everything is stored in files mentioned in the commands. At any stage if something went wrong, clear all the files and perform the steps once again.

There are two sections

1. RootCA Server   --  Need to perform only once.

2. Generating wildcard certificates for xyz.com domain -- Need to perform once per domain to create wildcard certificates. Need to perform once per site per domain to create individual certificates per site.


RootCA Server
============
1. Install required packages.

# yum install openssl -y

2. Generate XYZRootCA certificates

# mkdir /opt/XYZRootCA
# cd /opt/XYZRootCA
# openssl genrsa -out XYZRootCA.key 2048
# openssl req -x509 -new -nodes -key XYZRootCA.key -sha256 -days 10950 -out XYZRootCA.pem

#Provide information as given below

Country Name (2 letter code) [XX]:IN
State or Province Name (full name) []:Karnataka
Locality Name (eg, city) [Default City]:Bengaluru
Organization Name (eg, company) [Default Company Ltd]:XYZ Solutions Pvt. Ltd
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:XYZRootCA
Email Address []:info@xyz.com

3. Convert .pem to .crt

# openssl x509 -outform der -in XYZRootCA.pem -out XYZRootCA.crt



Generating wildcard certificates for xyz.com domain
===========================================
1. Generate CSR for *.xyz.com

# openssl genrsa -out XYZWildcard.key 2048
# openssl req -new -key XYZWildcard.key -out XYZWildcard.csr

#Provide information as given below
Country Name (2 letter code) [XX]:IN
State or Province Name (full name) []:Karnataka
Locality Name (eg, city) [Default City]:Bengaluru
Organization Name (eg, company) [Default Company Ltd]:XYZ Solutions Pvt. Ltd
Organizational Unit Name (eg, section) []:Infra Support
Common Name (eg, your name or your server's hostname) []:*.xyz.com
Email Address []:infrasupport@xyz.com

2. Using CSR generated above (As Shown in Step no:1), generate a wildcard certificate for *.xyz.com also get it signed by XYZRootCA as well.

# openssl x509 -req -in XYZWildcard.csr -CA XYZRootCA.pem -CAkey XYZRootCA.key -CAcreateserial -out XYZWildcard.crt -days 3650 -sha256

3. Import XYZRootCA.crt to trusted root certificates

# yum install ca-certificates
# update-ca-trust force-enable
# cp XYZRootCA.crt /etc/pki/ca-trust/source/anchors/
# update-ca-trust extract



References:
###########
  1. https://datacenteroverlords.com/2012/03/01/creating-your-own-ssl-certificate-authority/
  2. http://linoxide.com/security/make-ca-certificate-authority/
  3. https://blog.celogeek.com/201209/209/how-to-create-a-self-signed-wildcard-certificate/
  4. http://stackoverflow.com/questions/13732826/convert-pem-to-crt-and-key
  5. https://serversforhackers.com/self-signed-ssl-certificates
  6. http://kb.kerio.com/product/kerio-connect/server-configuration/ssl-certificates/adding-trusted-root-certificates-to-the-server-1605.html



A Go-Ready vagrant setup

Hello,

I hope you know what is a Vagrant. If you don't , please visit https://www.vagrantup.com/intro/index.html.

For a Vagrant setup Vagrantfile is important. In the Vagrantfile we can define so many parameters for the VM we would like to build, for example IP Address, Hostname, Port Forwarding and while spinning the VM itself we can install the new packages and make our development or testing environment ready when ever we want.

I dont write Installation of Vagrant here, because their documentation is excellent and I dont want to duplicate it. If you want to install Vagrant , look at https://www.vagrantup.com/downloads.html and VirtuboxVM is one of pre-requisite for Vagrant and I hope you know how to install VirtualBox, if you dont know then look at https://www.virtualbox.org/wiki/Downloads.

Now I assume , you have installed Vagrant and VirtulBox.  Whether you are using Windows or Linux commands are same , just use your senses at path format which is different for Windows and Linux.

Here I will show you how to generate a new Vagrant file and how to use it as per our requirement.
Open you command prompt or powershell prompt depends on the OS and type as


mkdir vagrant_1
cd vagrant_1
vagrant init

Here vagrant_1 is the directory name where I have initialized the vagrant and you can replace it with anything you want. If you see contents of vagrant_1 directory after executing vagrant init , you will see a file with name Vagrantfile.

This is our main file. Open it with your favorite editor like Sublime, Atom , Brackets or any other you like.

Now observe carefully. Remove everything between

Vagrant.configure("2") do |config|
end

Now lets define some configuration.

Vagrant.configure("2") do |config|
config.vm.define "vagrant-centos01" do |vc01|
vc01.vm.box = "centos/7"
vc01.vm.hostname = "vagrant-centos01"
vc01.vm.network "private_network", ip: "192.168.20.20"
end
end

Lets go through each of them ,

1. With Vagrant.configure("2") do |config| , we saying to Vagrant that use Vagrant from 1.1+ to 2.0.X.

2. With config.vm.define "vagrant-centos01" do |vc01| we are saying as define or create a new VM with name as vagrant-centos01

3. With vc01.vm.box = "centos/7" , we are saying as for use centos 7 box. if you centos-7 not available locally , Vagrant download it from Hashicorp.

4. vc01.vm.hostname = "vagrant-centos01" , says what is the hostname

5. vc01.vm.network "private_network", ip: "192.168.20.20" , says what is the private IP or static IP and this is similar to Host-Only adapter at VirtualBox.

Thats it, A very basic VM setup is ready with hostname and Private IP. After saving this configuration use command as

vagrant up

and then

vagrant ssh 

To login into that machine. And this is very basic Vagrantfile setup. The deeper you dive the complex and beautiful it will.

For more information on building a Vagrantfile , check https://www.vagrantup.com/docs/vagrantfile/


Hope that helps.


=======================THIS IS NOT THE END===========================


Dell iDRAC Web GUI Error – ERR_SSL_SERVER_CERT_BAD_FORMAT


Issue :- 

iDRAC web GUI console unable to launch due to the SSL Certificate issue.

Error: -

doesn’t adhere to security standards.
ERR_SSL_SERVER_CERT_BAD_FORMAT



Reconfigure Self Signed Cert :–

1 )  ssh to iDRAC ip  and supply iDRAC user and password ( default is user:root , pass : calvin ).
       ssh -o "IdentitiesOnly yes "  root@<drac ip>
Ex :-
   [somasekhar.a@test ~]$ ssh -o "IdentitiesOnly yes"  root@192.168.0.122

2) Run the below command.
    /admin1-> racadm sslresetcfg
    Certificate regenerated successfully and webserver restarted
  Now try to relaunch iDRAC web GUI console. Still if its not working then have to soft reset iDRAC system. Run the below command
  racadm racreset soft
Ex:-
/admin1-> racadm racreset soft
RAC reset operation initiated successfully. It may take up to a minute 
for the RAC to come back online again.
Wait for 2/3 minutes then try to relaunch iDRAC web GUI console.

Prefork Multi Processing Module for Apache

MPM stands for Multi Processing Module and this module implements a non-threaded pre-forking web server.

MPM isolate each request , so single request wont effect any other request.

MaxRequestWorkers is proportional to Physical RAM. More value more requests so make sure we got more RAM available for that server.

=====How it Works

There is a process named as "Control Process" and it is responsible for launching child process and these child processes will listen for requests and serve them once they arrive. And Apache by default will maintain serveral spare child process so that client request doesn't have to wait until new child process created.

And following parameters are responsible for regulating these child process.
1. StartServers
2.MinSpareServers
3.MaxSpareServers
4.MaxRequestWorkers

The default value for MaxRequestWorkers is 256 , so a server with untouched MaxRequestWorkers parameter can handle 256 requests at a time and you can define your custom value according to your requirement but this proportioanl to availablity of RAM.

To have apache process to bind with port 80 , main parent process will start with root user
but all child process with start with apache to have limited access but all the content that should serve by child process should let them access it. So if some content not accessible , check whether child process which are owned by apache user&group authorized to access that content or not. Noob style just check that folder got owner ship for apache or not.

MaxConnectionsPerChild : Once a child process created , how many requests it can serve before it get killed.

MaxSpareServers Directive
-------------------------

This is the parameter to specify number of spare connection apache control process should create.
Default value is 10 and syntax is as below

Syntax: MaxSpareServers 10

If MaxSpareServers < MinSpareServers , then apache will adjust it MinSpareServers+1 automatically.

If MaxSpareServers > current Idle child/spare process then apache will kill those excessive spare process.

NOTE:
1. Dont ever set this value to a large number
2. If your website is a very busy website, turning off this is a good idea.

MinSpareServer Directive
------------------------

Syntax: MinSpareServers 5

This is the minimum threshold value of number of spare connections. If apache has found less number of spare connection than minimum threshold connections then it will create connections in per socond manner. like

1st second 2^0 connections
2nd second  2^1 connections
3rd second  2^2 connections 

like this it will move till creating 32 connections per second and once it reaches minimum spare connection threshold apache will stop creating spare connections.

Note:
1. Can turn off if your website is a very busy one.
2. Never set this parameter to a large number.

StartServers Directive
----------------------

Syntax: StartServers number

Number of child process should create at the time of Apache startup. And the default differs from
MPM to MPM.

Workder MPM has default value     3
Event  3
prefork                                             5
mpmt_os2                                       2