Saturday, December 4, 2021

Docker Basics

docker container run ubuntu

it will run the image and exit the container state

docker container run ubuntu sleep 60

this container will run for 60 second

docker container run -d ubuntu

-d will run in detach mode

if you want to run a container continously in detach mode

docker container run -d -it ubuntu

if you want go to inside container after creating it

docker container run -it ubuntu /bin/bash


exit from container without exit status of container
ctrl+pq

to check

docker container run stats c813c93fa156
CONTAINER           CPU %               MEM USAGE / LIMIT       MEM %               NET I/O             BLOCK I/O           PIDS
c813c93fa156        0.00%               6.898 MiB / 985.3 MiB   0.70%               44.5 MB / 332 kB    6.02 MB / 142 MB    56

cpu, mem usage

expose a port for a container -p 3600:80
docker run -it -d -p 3600:80 bash_nginx

difference b/w docker stop and docker kill
stop - will stop properly gracefully.
kill - stop forcefully

copy a file from local host to container

docker container cp man container_id:/tmp

how to download a image on local system
docker container export container_id > name.tar
docker container export container_id -o name.tar


how to upload a exported image to docker image
docker container import name.tar any_img_name

how to give tag
docker tag mysql manjeetyadav19/sqlserver

how to push image on docker hub
login 1st on docker
docker image push manjeetyadav19/sqlserver

how to check volume
docker volume ls

how to attach host volume on container
docker run -it -d -v myvolume:/tmp --name mynewcon ubuntu /bin/bash

how to check if volume is attached or not with container
check with docker container inspect

lab
create a mysql container, and mount a volume,
create a database india.
stop container
create another container attach same volume /var/lib/mysql to the container
and check if india database is there?


how to create docker private registery.
create a server
install docker package
create container, deploy registery image on it,
create docker image tag and push image to private repository
check image on the path http://127.0.0.1:5000/v2/_catalog

docker image tag nginx 127.0.0.1:5000/nginx
docker image push 127.0.0.1:5000/nginx

how to push insecure content
e.g.
docker image push 172.31.30.125:5000/registry

https content not allow to push,

do below config for that
daemon.json
{
    "insecure-registries" : ["172.31.30.125:5000"]
}

save it in /etc/docker and restart docker service
now try again to push
docker image push 172.31.30.125:5000/registry

how to do it with https?
create cert 1st, and deploy cert.

create folder certs, run below cmd,
openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt
enter only provide
Common Name (eg, your name or your server's hostname) []:repo.docker.local

create folder rep.docker.local in /etc/docker/certs
copy domain.crt as ca.crt in /etc/docker/certs/rep.docker.local
restart docker service
create docker secure docker private repo as below

docker container run -d -p 5000:5000 --name secure_registry -v $(pwd)/certs/:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key registry

docker image tag nginx repo.docker.local:5000/nginx
docker image push repo.docker.local:5000/nginx


Dockerfile
create your own custom image

if you creating Dockerfile with different name you can run it with -f

FROM ubuntu
RUN apt-get update && apt-get install -y apache2
RUN apt-get install -y tree openssh-server openssh-client
RUN cd /var/www/html
RUN echo "Welcom to india" > /var/www/html
RUN service apache2 start

docker build -t myimage:1 .
docker build -t myimage:1 -f myfile .    if using diff name
docker build -t myimage:1 -< myfile .    if using diff dockerbuild file name

if you build your file from tar folder
 docker build -t myimage:1 -f myfile -< /cloud/cloudknowledges.tar.gz    

do check about build file
docker image history ba6acccedd29

docker file layer architecture
eg if you have 5 layer
it will build 5 image 1st time,

next time if you do any change in image from bottom, it will not build again all 5 layer it will pick from cache and add additional changes on last layer.
But if you do changes in middle or top, so it will build directly from there again.

Note: so if you working in a company try to do addition from the bottom of dockerfile not on top or middle otherwise it will take so much time in building the image.

LABELS in dockerfile
it will not build, it will add extra layer in dockerfile, its like comment, eg develper email id, phone no.
also can check labels from docker inspect cmd
docker container inspect container_id

ENV
when some value need to call manytime we can define as ENV var.



FROM centos
LABEL Name="Sanjay Dahiya"
LABEL EmailId="sanjay.dahiya332@gmail.com"
LABEL Mobile="8802767619"
ENV Name=manjeet
ENV Pass=manjeet
RUN useradd $Name && echo "$Name:$Pass" | chpasswd
RUN touch india
RUN touch abc
RUN touch abc1
RUN touch abc2
RUN touch abc3
RUN yum update -y && yum install -y httpd
#USER $Name
WORKDIR /var/www/html
COPY man /var/www/html
ADD https://www.free-css.com/assets/files/free-css-templates/download/page272/tivo.zip /var/www/html
RUN yum install unzip -y
RUN unzip tivo.zip
RUN rm -rf man tiva.zip


FROM centos
LABEL Name="Sanjay Dahiya"
LABEL EmailId="sanjay.dahiya332@gmail.com"
LABEL Mobile="8802767619"
ENV Name=manjeet
ENV Pass=manjeet
RUN useradd $Name && echo "$Name:$Pass" | chpasswd
RUN touch india
RUN touch abc
RUN touch abc1
RUN touch abc2
RUN touch abc3
RUN yum update -y && yum install -y httpd
USER $Name
WORKDIR /var/www/html
COPY man /var/www/html
CMD ["tree"]


lst cmd tree will run in the end.
CMD ["python"] it will provide default python shell, but before it need to install python package



copy cmd copy a file from the your base machine to container you want to build

how to ssh docker container
by default ssh package not installed, and port is also not opened, so need to expose port and install package

FROM centos
RUN apt-get update && apt-get install -y openssh-server \
openssh-client \
ENV Name=manjeet
ENV Pass=manjeet
RUN useradd $Name && echo "$Name:$Pass" | chpasswd
RUN mkdir -p /var/run/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

expose container port to he host machine, then we are able to ssh container host from outside.

Dockerfile to install website from internet
FROM centos:latest
#MAINTAINER: sanjay.dahiya332@gmail.com
RUN yum install -y httpd \
zip \
unzip
ADD https://www.free-css.com/assets/files/free-css-templates/download/page247/kindle.zip /var/www/html
WORKDIR /var/www/html
RUN unzip kindle.zip
RUN cp -rvf markups-kindle/* .
RUN rm -rf __MACOSX markups-kindle kindle.zip
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
EXPOSE 80


How to create image without writing docker file.
docker image build -t myimage: -<<EOF
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y apache2
EOF


Docker-compose benifit
if you run a container or app in docker compose, it will create destroy within the 1 sec in 1 cmd.
if you want to create 50 container and you want to diff-2 configuration you will define all your diff deployment in one docker-compose.yml file

with docker compose up it will create and with down, it stop and deprovision.
If you need to run same kind of project that you created once, its portable, you can share on another project also.
 

install wordpress application

lab 1 install by docker cmd
docker container run --name db-mysql -e MYSQL_ROOT_PASSWORD=mypassword -d mysql:5.7
docker container run -d -p 8000:80 --name my-wordpress -e WORDPRESS_DB_HOST=172.17.0.2:3306 -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=mypassword wordpress

lab 2 install wordpress by docker compose
version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: wordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       WORDPRESS_NAME: wordpress
volumes:
 db_data: {}

............................
version: '3.3'

services:
      app1:
          image: nginx
          volumes:
            - /root/man/:/var/www/html

          ports:
            - "8001:80"
          restart: always

      app2:
          image: nginx
          volumes:
            - /root/man1/:/var/www/html

          ports:
            - "8002:80"
          restart: always
..........................................

version: '3.3'

services:
      app1:
          build: .

      #    volumes:
      #      - /root/man/:/var/www/html

          ports:
            - "8001:80"
          restart: always

      app2:
          build: .

       #   volumes:
       #     - /root/man1/:/var/www/html

          ports:
            - "8002:80"
          restart: always

.........................

container scale up
docker-compose scale app1=4 app2=2

To list deploy container from docker compose
docker-compose ps

Stop all deployment from docker container
docker-compose stop

Start just stop previous stopped container
docker-compose start

Remove stop containers
docker-compose rm

if you deploy a app with docker-compose with different docker-compose file name
docker-compose -f cloud.yml up -d

docker-compose support json and yml both file for build
docker-compose -f cloud.json up -d

...................................

version: "3.3"
services:
      app3:
        build: .
        image: app3_webapp:1


docker compose --help
  build              Build or rebuild services
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information

if you want to run spacific cmd only not all command in docker-compose use cmd with docker-compose
e.g.
docker-compose build
 

docker-compose event
it will print the real time event of container


 if want to execute a file with docker-compose container
docker-compose exec cloudknowledges ls

if you want to see the images that deployed by docker-compose you can check by
docker-compose images

if you want to see container immeditely
docker-compose kill

if you want to see docker container logs
docker-compose logs

if you want to pause a container
docker-compose pause

if you want to pull the images that is defined in docker-compose file.
docker-compose image pull

if you want to push your image to docker repo
docker-compose image push

Docker Network

default network 172.17.0.0/16  docker0 - bridge n/w g/w - 172.17.0.1
 
Why need to create network,
by default range is 256 host, if want more container can create another n/w
if we have req. we have 3 tier n/w and we want to each web,db, and app in diff n/w we can create separate n/w

if you have default and customer n/w and you dont define n/w while creating container, it will add in default n/w

Scenario
If you want to communicate 3 different n/w in docker with each other?
sol
1. create another n/w and connect this with each n/w so now they can communicate via this another n/w
2. do port mapping with host machine eth0 ip
3. overlay network



To check network
docker network ls

to check ip range, g/w for a docker n/w
docker network inspect nw_id

For connection b/w docker bridge n/w and host machine 1 more interface work, it will visible only when you have any running container.

How to define hostname to a container and dns?
docker container run -it --hostname cloud --dns 8.8.8.8 ubuntu

docker network create dev-team
docker network create dev-team --subnet=10.100.0.0/24

creating docker in custom n/w
docker container run -it --network=dev-team ubuntu

if want to assing specific ip to a container
docker container run -it --network=prod-team --ip 10.200.0.100 ubuntu

Lab
Install 2 container in different subnet with port mapping e.g -p 8001:80, -p 8002:80
install apache2 in both.
Now try to access by ip, from opposite container.
use wget, you will not able to access by container ip.
now try with host private ip eth0 port ip.
you will be able to access each other.

Lab
create a 3rd subnet network, 10.99.0.0
connect both different subnet network with 3rd n/w
docker network connect n/w_id container_id_1st
docker network connect n/w_id container_id_2nd
now we can connect with container new interface ip that is received from 3rd subnet
e.g
wget 10.99.0.2

create a container in host network
docker run -it --network=host ubuntu
Use case of Host n/w when we dont want to isolate host network with container and we want common network for host and container

create a container in none network
docker run -it --network=none ubuntu


How to connect a container from bridge to none or host network, and how disconnect container from a network?
docker container network disconnect 2ba3783510cc 579a8f8b10c4

docker network ls
docker container ls
docker network disconnect 2ba3783510cc 579a8f8b10c4
docker network connect 3da33e43949e 579a8f8b10c4


Difference in docker swarm and docker container
docker swarm provide clustering of nodes
it provides 100% availability, container installed in diff-diff nodes

Scenario
If you have 1 manager and 2-3 worker node,
so if worker nodes get down, no effect other node will take those container or master node takes those container.
If you have master gets down, then will be a problem

Sol. Make 2-3 nodes as master, so if 1 master node gets down other will take over and cluster keep working.
Or make each node as work and master, so cluster keep running even 1 nodes remain working.

In swarm,
each node have ingress LB, so each container transfer traffic to ingress and ingress transfer to node ip port.


How enable swarm master node?
docker swarm init
and you will get a cmd after that to join other node as work node with swarm 


docker swarm join \
    --token SWMTKN-1-2l1t1rqnhpmuoqzd2zgnvnyjhkktqsaoapgn347c5l7ctme2j9-0qnk6hzixjyajlwe0f8ojaexk \
    172.31.30.125:2377

how to check if node is as master or worker and if multiple master node, which one is leader.
docker node ls
docker node inspect node_id

how to promte a node as a master
docker node promote node_id
docker node demote n74zs69msevkzoda6llcq4qr1

how to remove a node from cluster
docker node rm node_id
but condition node must be down.
if you want to remove forcefully
docker node rm node_id --force

to check if swarm is active on a node
docker info

if node want to leave swarm cluster
docker swarm leave
docker swarm leave --force

if you dont have join-token as work, or you need to fetch it
go to master
docker swarm join-token worker


if you want to join a node as manager, you can fetch manger docker from the manager node.
and run that token on a node which you want to join as manager.
docker swarm join-token manager

Deploy a service with the help of swarm
we do it by create service and we define container in service, we can also define about its replica here.
docker service create --replicas 4 nginx
docker service create --name web-server --replicas 4 nginx

replicas deploy container in each node, if any container gets down it will create another one right away.

if you want to delete container forcefully
docker container rm -f container_id


create a service with port mapping.
docker service create --name nginx-service -p 8000:80 --replicas 4 nginx

how to check service container running
docker service ps service_id

if you access node ip with port it will access container application, does not matter on which node its hosting.




Update service
whenever update service container, it will update container on 1 container 1st, if that success it will update on the remaining container.

FROM centos
RUN yum update -y && yum install apache2 \
zip \
unzip
ADD https://www.free-css.com/assets/files/free-css-templates/download/page247/kindle.zip
WORKDIR /var/www/html
RUN unzip kindle.zip
RUN cp -rvf markup-kindle/*
RUN rm -rf __MACOSX markups-kindle kindle.zip
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
EXPOSE 80

Lab
create a dockerfile
create image from it.
docker image build -t webapp:1 .
create image from same dockerfile on all node.
now create docker service.
docker service create --name app-server -p 8001:80 webapp
now scale up
docker service scale zwyc4aivmiyz=4
Now you can access this app from outside also, and within node also with local ip.
even you can access opposite node container from a node, doesnt matter where is container running, you will able to access by service

Lab
if you want to update image.
1st build the image again with new version
docker image build -t webapp:2 .
Do it in all nodes
now come back to master node.
run update cmd
docker service update --image image_name service_id
docker service update --image webapp:1 zwyc4aivmiyz
now check again new content should be displaying

In case your update got failed. you can do rollback
docker service rollback service_id
docker service rollback zwyc4aivmiyz

Docker swarm visualizer
if you deploy container, and you want to check how many container on which node installed,
you can used web based visualizer

To run in a docker swarm:

docker service create --name=viz --publish=8080:8080/tcp --constraint=node.role==manager --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock dockersamples/visualizer

This container will run only on manager node with this  --constraint=node.role==manager


Labels

Default label
master , worker

User defined label
worker-1(ssd=true), worker-2
if you want suppose all pods should be deploy in worker-1, you will define while you create service

Label can set
From master
From worker

Use case:
If you have multiple node, but one of node have high configuration, and you want your most container deploy on that you can use label

How to check label
docker node inspect node_id

change node status pause, active, drain
docker node update --availability=active

User case
when we dont want to put more container on any 1 node,
we can put node - pause

when we want to remove container from your existing node, use case while we do patch upgrade activity etc.
we can use - drain


Lab - creating docker container with Ansible

install ansible on 1 of node.
install pip, python and docker on other nodes
pip install docker-py
and do passwordless access from ansible machine.

if aws machine first enable epel
RHEL 7:
Install and enable the EPEL release package for RHEL 7.
sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

/etc/yum/pluginconf.d/priorities.conf
enabled = 0

yum update.

copy sshd file from your base machine to aws machine, and paste it /etc/ssh
restart sshd service
systemctl restart sshd

pl.yml
- hosts: all
  tasks:
    - docker_container:
      name: web-container
      image: ubuntu:14.04
      command: sleep infinity
      ports:
        - "80:80"

.....................
- hosts: all
  tasks:
    - docker_container:
       name: web-container
       state: stopped


Lab install ansible in docker container

create container .
update, install python, openssh-server, openssh-client,
set root passwd
go to
/etc/ssh/sshd_config
PermitRootLogin yes
PasswordAuth yes

restart sshd service
ssh-copy-id to client machine from ansible master machine
    
- hosts: all
  tasks:
    - apt:
        name: apache2
        state: present
    
    - copy:
        src: /tmp/sourcecode/
        dest: /var/www/html

    - service:
         name: apache2
         state: started


#!/bin/bash
###########Assigning standard docker variables#########
DATE_TIME=`date "+%m-%d-%y%"`
IMAGE_NAME="preventivecontrol"
PORT="9095"
CONTAINER_NAME="preventive-control"

#################display all version of preventivecontrol and enter version as input ########
echo "The current preventivecontrol version is below:"
docker images | grep "preventivecontrol"
echo "please enter the version"
read ver

########## Remove old container##########

docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME

######## Rename old WAR file #########

mv /home/aexp-user/Preventivecontrols/Preventive-control-LOCAL/PreventiveControl.war PreventiveControl$DATE_TIME.war

######## COPY AtulWeb WAR FILE ##########

#aws s3 cp s3://man-420244912485-user/arunk/war/sample.war PreventiveControl.war

###### Build the image with latest WAR FILE #######

docker build -t $IMAGE_NAME:$ver .

#######Run the container from the build########

#docker run -d -p $PORT:8080 --name $CONTAINER_NAME $IMAGE_NAME:$ver

##########Delete old preventivecontrol
#while [ True ]
#do   
#    echo "Press"
#    echo "1. For All version of Preventivecontrol image"
#    echo "2. For Delete old of Preventivecontrol version image"
#    echo "3. For Exit"
#    read choose
#    if [ $choose -eq 1 ]
#    then
#        echo "Below are the current version:"
#        docker images | grep "preventivecontrol"
#    elif [ $choose -eq 2 ]
#    then
#        echo "Below are the current version:"
#        docker images | grep "preventivecontrol"
#        echo "Enter the older version you want to delete:"
#        read delver
#        docker rmi $(docker images | grep $delver | awk '{print $3}')
#    elif [ $choose -eq 3 ]
#    then
#        echo "Exiting..."
#        exit 1
#    else
#        echo "Wrong input.."
#    fi
#done


you have 2gb docker image now, how do you optimize it? 

Choose a suitable base image
use such alpine image lightweight, such as debian, have a slim tag,

Multi-stage builds
You need to install a package manager,
you don’t need the package manager (such as pip) to run your application!
The package manager might cache downloaded dependencies (see below for how to avoid it)
You don’t need that cache to run your application!
You need to compile native code (e.g. written in C/C++) with compiler tool-chains, e.g. to be able to install Python extensions that include native modules
You don’t need the compiler to run your application!

Consolidate RUN commands
you should build a single RUN command that performs all these steps, instead of having multiple RUN commands.

Squash image layers

Save space when installing dependencies

 

how to enter in running docker container?



 

No comments:

Post a Comment