Docker & Kubernetes - rlip/java GitHub Wiki

docker run -d -p 80:8080 docker/getting-started
where:
-d - run the container in detached mode (in the background)
-p 8080:80 - map port 80 of the host to port 8080 in the container
docker/getting-started - the image to use

docker run -it centos bash //it przełącza na opdalany kontener
exit //wychodzi z kontenera

docker pull nazwa //tylko ściąga, nie uruchamia

docker ps //dziłające kontenery
docker ps -a //wszytkie kontenery

docker stop nazwaKontenera_lubId  //zatrzymuje kontener
docker rm nazwaLubId //usuwa kontener

docker images //lista images
docker rmi nazwaImaga //usuwa obraz, trzeba się upewnić, źe nic go nie używa

docker exec nazwaLubId cat /etc/hosts //uruchamia komendę na działającym kontenerze
docker exec -it some-postgres bash ///przełączna na kontain er uruchamiając basha
docker exec mysql-db mysql -pdb_pass123 -e 'use foo; select * from myTable'  //select

docker attach nazwaLubId //przełącza na działający container
docker attach --sig-proxy=false nazwaLubId // j.w + pozwala wyjść przez ctrl+z

docker inspect nazwaLubId - dużo informacji, m.in ip adres (wewnętrzy), zmienne środowiskowe
docker info //info o samym dokerze

docker history idImagu  // pokazuje historię jak obraz został zbudowany

RUN

docker run ubuntu:artful // pobranie konkretnej wesji - można zobaczyć na hub.docker.com, domyślnie latest
docker run -d ubuntu sleep 150 // -d - uruchamia w tle, wykonuje sleep 150 bo inaczej ubuntu by się od razu zamknął

docker run -ti jenkins // uruchamia na 1 planie, dzięki -it można wyjśc przez ctrl+q+p albo po wpisaniu "exit"
docker run -p 8080:8080 jenkins // mapujemy port (zewnętrzny:wewnętzny), tak że będzie on dostepny też na swoim ip zewnętrznym
docker run -p 8080:8080 -v /home/roman/Desktop/temp/myjenkinsdata:/var/jenkins_home -u roman jenkins 
//-v - mapujemy jeszcze folder, żeby contener miał gdzie trzymać dane,
//-u jaki użytkownik ma zapisywać dane (u mnie nie było potrzebne)

docker run python:3.6 cat /etc/*release*  //sprawdzenie jaki system
docker run --name alpine-2 --network=none alpine //uruchamia alpine pod nazwą zlpine-2 i sięcią typu none

// uruchamia mysql:5.6 ustawiając hasło bazy, nazwę kontenera i network
docker run -d -e MYSQL_ROOT_PASSWORD=db_pass123 --name mysql-db --network wp-mysql-network mysql:5.6

// uruchamia kodekloud/simple-webapp-mysql udostępniająć port 38080 na hoście,
// ustawia env vriable DB_Host i dołącza do sieci wp-mysql-network
docker run -d -p 38080:38080 -e DB_Host=mysql-db --network wp-mysql-network --name webapp kodekloud/simple-webapp-mysql

// uruchomia z ustawieniem hosta 
docker run -dit--name nginx-with-explicit-hosts --add-host=facebook.com:127.0.0.1 nginx: latest

Dockerfile

FROM ubuntu

RUN apt-get update && apt-get install -y python python-setuptools python-dev python3-pip
RUN pip3 install flask flask-mysql

COPY app.py /opt/app.py

ENTRYPOINT FLASK_APP=/opt/app.py flask run --host=0.0.0.0

BUILD

docker build . -t rlip/my-custom-app:tag  //budowanie + dodanie nazwy, po : można też ustawić tag
// -f Dockerfile2 --budowanie z innego dockerfila

docker login
docker push rlip/my-custom-app

Czyszczenie

docker system df -v //statsy

docker system prune //usuwa wszystko nieużywane
docker system prune -a // usuwa wszystkie images
docker system prune --volumes //usuwa volume

docker container prune //usuwa wyłączone kontenery
docker image prune -a //usuwa images niepołaczone z kontenerami

docker stop $(docker ps -a -q) //zatrzymuje wszystkie kontenery
docker rm $(docker ps -a -q)  //usuwa wszystkie kontenery

ENV VARIABLES

docker run -e APP_COLOR=blue simple-webapp-color
// podejrzeć variable można przez docker inspect nazwaLubId

CMD & ENTRYPOINT

CMD sleep 5 // określa co ma bć brane pod uwagę, żeby kontener się nie wyłaczył
//można ustawić to przy runie: docker run ubuntu-sleeper sleep 10

ENTRYPOINT ["sleep"] //mając to wystarczy podać argument: docker run ubuntu-sleeper 10

CMD["5"] // domyśny paramert do entrypoint
// i tak można to wszystko nadpisać:
// docker run --entrypoint sleep2.0 ubuntu-sleeper 10

Docker Compose

https://docs.docker.com/compose/install/ Zainstalować, stworzyć plik docker-compose.yml i:

docker-compose up -d
docker-compose -f compose2.yml up -d  # z inną nazwą pliku
docker build . -t votting-app
docker run -p 5000:80 votting-app

docker run -d --name=redis redis
docker run --name db -p 5432:5432 -e POSTGRES_PASSWORD=postgres -d postgres

docker build . -t worker-app
docker run --link redis:redis --link db:db worker-app

docker build . -t result-app
docker run -d --link db:db -p 5001:80 result-app

To co wyżej w docker-compose.yml:

redis:
  image: redis

db:
  image: postgres:9.4
  environment:
    - POSTGRES_PASSWORD=postgres

vote:
  image: votting-app /// Można też build: ./vote - bo nie musi być zbudowane
  ports:
    - 5000:80
  links:
    - redis

worker:
  image: worker-app
  links:
    - db
    - redis

result:
  image: result-app
  ports:
    - 5001:80
  links:
    - db

W wersji 2+:

  • nie trzeba linków - bo są automatyczne,
  • trzeba podać jaka jest wersja pliku,
  • można podać depends_on:(tu enter) - nazwaObrazu1 żeby ustalić kolejność
Wersja 3.0:
services:
  db:
    environment:
      POSTGRES_PASSWORD: mysecretpassword
    image: postgres
  wordpress:
    image: wordpress
    links:
    - db
    ports:
    - 8085:80
version: '3.0'

Volume

docker volume create data_volumne // tworzy volum w /var/lib/docker/volumne, mozna go później użyć:
docker run -v data_volume:/var/lib/mysql mysql //jak się nie stworzy data_volume ręcznie to się zrobi automatycznie

docker run -v /data/mysql:/var/lib/mysql mysql //można też przechowywać dane w innej, niedokorewj lokalizacji (/data/mysql)

//-v nie jest najnowym podejściem, teraz używa się mount

docker run  --mount type=bind,source=/data/mysql,target=/var/lib/mysql mysql

Network

Dockerm ma wbudowane dns, że zamiast ip można wpisywać nazwę kontererów

docker run ubuntu //bridge - kontenery mają lokalną sieć, trzeba bindować porty
docker run ubuntu --network none //bez dostępu, np. kiedy kontener produkuje dane na dysk
docker run ubuntu --network host //automatycznie mapowanie, nie można uruchomić
/// większej liczby kontenerów działających na tym samym porcie

docker network create --driver bridge --subnet 182.18.0.0/16 custom isolated network

docker network ls // lista networków
docker inspect nazwaLubId // tu można podejżeć jakie sieci ma container
docker network inspect nazwaNetworka // szczegóły danej sieci np. adres podsieci 

//tworzenie sieci o nazwie wp-mysql-network typu bridge, o danej subnet i gateway
docker network create --driver bridge --subnet 182.18.0.1/24 --gateway 182.18.0.1 wp-mysql-network

//tworzenie sieci pomiędzy wieloma nodami w klastrze
docker network create --driver overlay --subnet 10.0.9.0/24 my-overlay-network 
//tworzenie klastra i przypisanie go do sieci overlay
docker service create --replicas 2 --network my-overlay-network nginx


//łączenie z siecią
docker network connect (...)

Docker swarm

najlepiej nieparzystą liczbę masternods. musi być większość managerów aktywna bo inaczej nie będzie można robić wielu akcji na klastrze (ale podstawowe będą działać). Wtedy trzeba albo przywrócić większość, albo można klaster przeksztaucić na taki z mniejszą liczbą nodów: docker swarm init --force new cluster --advertise-addr 192.168.56.101

docker swarm init --advertise-addr 192.168.56.101  // tu trzeba wybrań dla jakieś sieci uruchamiamy swarm
docker node ls 

docker swarm join --token tu_token  // dodanie się na innej maszynie do clastra jako worker
docker swarm leave //opuszczenie clastra - zrobienie na down
docker node rm nazwa   // tu usuwa

docker swarm join-token manager  //tworzy joina żeby dodać managera
docker node promote nazwa // promuje noda nazwa do managera - musi być wykonane na master nodzie

Docker service

Jedna lub więcej instancji tego samego kontenera. Pozwala zarządzać klasterm - nie trzeba uruchamiać workerów na każdym nodzie osobno.


Tworzy 3 instancje wokrera na dostępnych nodach,

  • jak liczba mniejsza niż dostępbnych nodów to jakieś nody zostaną puste,
  • jak większa to bedzie więcej niż jeden na jednym nodzie,
  • jak jakiś nod padnie, to tyle ile padło instancji tyle zostanie usuchomionych na innych nodach
docker service create --replicas=3 my-web-server

Tworzy po jednej instancji na każdego noda

docker service create --mode global my-monitoring-agent
docker service update-replicas=4 web-server // aktualizacja
docker service ls //lista serwispw
docker service ps //lista tasków (1 do 1 do kontenerów)
docker service update nazwaLubId --publish-add 5000:80 //publikuje port
docker service rm nazwaLubId // usuwa serwis

docker service create --replicas 2 --name nginx nginx // tworzy servis z 2 replikami

docker node update --availability drain docker-master // z tym na masterze nie będzie serwisów
 tylko zarządzanie, a domyslnie ma inne serwisy

docker service create --replicas=2 -p 80:5000 my-web-server // to zadziała, bo choć nie można mapowiać
// dwóch tych samych portów 5000 z dwóch kontenerów, to serwise ma wbudowaną sięć z load balancerem,
// który to ogarnie. Działa na całym klastrze. Jak się podłączamy do noda bez workera, to tam też działa
//load balancer, który przekieruje na działające workery w działających nodach

Docker Stack

Zbiór docekrowych serwisów tworzących aplikację Można zwizualizować to co jest gdzie za pomocą vizualizera (hub.docker.com > vizualizer)

docker stack deploy voting-app-stack --compose-file docker-stack.yml
docker service ls

Zamiast docker run ..., trzeba zrobić serwisy docker service create ... a docker-compose.yml ma dużo nowych możliwości (wym. wersja 3):


version: 3
services:
    redis:
        image: redis
        deploy:
            replicas: 1    //ile replik
            resources: (...) // można ustawić użycie cpu i pamięci
            placement:     //opcjonalnie moża podać położenie
                constrains:   //i warunki
                    - node.hostname == node1
                    - node.role == manager       



Docker registry

jest dostępne na docker hub

docker run -d -p 5000:5000 --restart always --name registry registry:2
docker pull hello-world
docker tag hello-world localhost:5000/hello-world //trzeba stagować
docker push localhost:5000/hello-world 

docker exec -it registry /bin/sh
 ls /var/lib/registry/docker/registry/v2/repositories/hello-world/

$ docker pull localhost:5000/hello-world

repozytorium można jeszcze zobaczyć w przeglądarce instalując jeden z frontendów, będzie pod http://localhost:8080/ np.

sudo docker run \
  -d \
  -e ENV_DOCKER_REGISTRY_HOST=registry \
  -e ENV_DOCKER_REGISTRY_PORT=5000 \
  -p 8080:80 \
  -link registry:registry \
  konradkleine/docker-registry-frontend:v2

Kubernetes

https://github.com/mmumshad/kubernetes-example-voting-app

Każdy kontener jest w osobnym podzie. Może być więcej kontenerów w 1 podzie, wtedy kożystają z 1 pamięci są dostępne dla siebie pod adresem localhost. Każdy pod musi mieć swoją deficnicję w yml. Trzeba zrobić serwis dla każdego poda, żeby udostępnic go w workerze. Pod o spec LoadBalancer będzie dostępny z zewnątrz.

kubectl create -f voting-app-pod.yml 
kubectl get pods

kubectl create -f voting-app-service.yml 
kubectl get services