Docker(3)

Nginx Load Balancing

  • docker의 load balancing은 랜덤
  • nginx의 load balancing default 값은 라운드로빈방식
  • 가중치로 서버부하를 임의대로 조절할 수 있음
sudo apt update
sudo apt-get -y install nginx
sudo nginx -v
sudo systemctl status nginx.service

docker run -it -d -e SERVER_PORT=5001 -p 5001:5001 -h alb-node01 -u root \
--name=alb-node01 dbgurum/nginxlb:1.0

docker run -it -d -e SERVER_PORT=5002 -p 5002:5002 -h alb-node02 -u root \
--name=alb-node02 dbgurum/nginxlb:1.0

docker run -it -d -e SERVER_PORT=5003 -p 5003:5003 -h alb-node03 -u root \
--name=alb-node03 dbgurum/nginxlb:1.0
// 3개의 nginx container 생성

docker ps

sudo netstat -nlp | grep 5001
sudo netstat -nlp | grep 5002
sudo netstat -nlp | grep 5003

cd /etc/nginx/
sudo mv nginx.conf nginx.conf.org
sudo nano nginx.conf

 
events { worker_connections 1024; }

http {

        upstream backend-alb {
                server 127.0.0.1:5001;
                server 127.0.0.1:5002;
                server 127.0.0.1:5003;
        }

        server {
                listen 80       default_server;
                listen [::]:80  default_server;

                location / {
                proxy_pass      http://backend-alb;
                }
        }
}

sudo systemctl restart nginx.service
sudo systemctl status nginx.service

sudo nano /etc/nginx/nginx.conf

 
events { worker_connections 1024; }

http {

        upstream nginx-lb {
                server 127.0.0.1:5001 weight=6;
                server 127.0.0.1:5002 weight=2;
                server 127.0.0.1:5003 weight=2;
        }
...

##

T1 -> docker run -it --name=add-net ubuntu:14.04 bash
T1 -> ifconfig
// eth0 한개 조회

T2 -> docker ps
T2 -> docker network create --driver=bridge web-network
T2 -> docker network ls

br-4c19ce133841: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.20.0.1  netmask 255.255.0.0  broadcast 172.20.255.255
        ether 02:42:b6:e4:e3:69  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0



T2 -> docker network connect web-network add-net
T2 -> docker exec add-net route

T1 -> ifconfig
// eth0, eth1 두개 조회

T2 -> docker network rm web-network
T2 -> docker container stop add-net
또는
T2 -> docker network disconnect web-network add-net
T2 -> docker network rm web-network

Docker 리소스에 대한 런타임 제약(resource limit)

  • Linux의 cgroups 기능 활용

Container 메모리 제한

sudo apt install sysstat
sar 2 5
iostat 2 5
top
df -h


sudo apt -y install htop
htop

docker run -d --memory=1g --name=nginx_mem_1g nginx

WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.

sudo nano /etc/default/grub

----
GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1"
----

sudo update-grub
sudo reboot
docker run -d --memory=1g --name=nginx_mem_1g nginx
docker inspect nginx_mem_1g | grep \"Memroy\"

            "Memory": 1073741824,

docker run -m=200m --memory-swap=300m -it -d --name=mem-test ubuntu:14.04
docker ps
docker inspect mem-test | grep -i memory

또는
docker inspect mem-test | grep \"Memory\"

      "Memory": 209715200,
      
docker inspect mem-test | grep \"MemorySwap\"

      "MemorySwap": 314572800,
  • –memory-swap 옵션이 -1로 설정된 경우, Container는 Host OS의 swap을 무제한으로 사용할 수 있음
  • 0이면 container swap

Container CPU 제한

docker run -d --name cpu_1024 --cpu-shares 1024 leecloudo/stress:1.0 stress --cpu4
docker run -d --name cpu_512 --cpu-shares 512 leecloudo/stress:1.0 stress --cpu4
ps -auxf | grep stress
docker stop cpu_1024 cpu_512
docker rm cpu_1024 cpu_512

docker run -d --name cpuset_1 --cpuset-cpus=2 leecloudo/stress:1.0 stress --cpu 1
docker run -d --name cpuset_2 --cpuset-cpus=0,3 leecloudo/stress:1.0 stress --cpu 2

  • Host에 CPU가 여러개 있을 때 –cpuset-cpus 지정해 container가 특정 CPU만 사용하도록 지정
  • CPU 집중적인 작업이 필요하다면 여러 개의 CPU를 사용하도록 설정해 작업을 적절하게 분배하는 것이 좋음
docker update --cpu-shares 512 -m 300M container_name
docker update --cpus=rate(%) container_name

docker run -d --name cpuset_1 cpuset-cpus=2 leecloudo/stress:1.0 stress --cpu 1

docker run -d --name cpuset_2 --cpuset-cpus=0,3 leecloudo/stress:1.0 stress --cpu 2
docker update --cpus=0.2 cpuset_2
//CPU 2개의 사용량을 20%로 제한

Container Disk block I/O 제한

  • Block I/O 옵션을 지정하지 않으면 I/O 무제한
docker run -it --rm ubuntu:14.04 bash
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct

10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.0437855 s, 239 MB/s

docker run -it --rm --device-write-bps /dev/sda:1mb ubuntu:14.04 bash
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct

10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 10.0299 s, 1.0 MB/s

docker run -it --rm --device-write-bps /dev/sda:10mb ubuntu:14.04 bash
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct

10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 1.01035 s, 10.4 MB/s

docker run -it --rm --device-write-iops /dev/sda:10 ubuntu:14.04 bash
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct

10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.905844 s, 11.6 MB/s

docker run -it --rm --device-write-iops /dev/sda:1 ubuntu:14.04 bash
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct


10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 18.0347 s, 581 kB/s

Volume

세가지 방법 제공

1. Volume (Docker 경로에 공유)

docker volume create xxx

2. Bind mount (직접경로를 지정해서 HOST에 공유)

-v “host_dir”(호스트경로) : “container_dir”(컨테이너경로)

3. tmpfs

–tmpfs /app

Bind Mount

Docker Volume활용한 Host OS 디렉토리와 Container patition과 파일 공유

mkdir hello1 hello2
cd hello1
cat > test1
test1
cd ..
cd hello2
cat > test2
test2

docker run -it \
--name ubuntu_volume \
-v /home/jeff/hello1:/hello1 \
-v /home/jeff/hello2:/hello2 \
ubuntu:16.04 bash

ls

cd hello1
mount
df -h
echo "hi" >> test1.txt
cat test1.txt
(ctrl + p + q)
cat test1.txt

docker inspect \
--format="" \
ubuntu_volume

Docker Volume 활용한 DB 중요데이터 보호

docker run -it --name=mysql-vtest -e MYSQL_ROOT_PASSWORD=mjeff \
-e MYSQL_DATABASE=dockertest -v /home/jeff/volume_test:/var/lib/mysql -d mysql:5.7

docker exec -it mysql-vtest bash

/etc/init.d/mysql start
mysql -uroot -p
show databases;
use dockertest;
create table mytab ( c1 int, c2 char);
insert into mytab values( 1, 'a');
commit;
exit
exit
cd volume_test/

docker stop mysql-vtest
docker rm mysql-vtest

docker run -it --name=mysql-vtest -e MYSQL_ROOT_PASSWORD=mjeff -e MYSQL_DATABASE=dockertest -v /home/jeff/volume_test:/var/lib/mysql mysql:5.7 bash


mysql -uroot -p

Docker Volume 활용한 웹 로그 분석

mkdir -p /home/jeff/nginx-log
docker run -d -v /home/jeff/nginx-log:/var/log/nginx -p 8011:80 nginx:1.20
cd nginx-log/
tail -f access.log

// 웹 서비스 로그 분석 : 지정 범위 내의 로그시간($4) 동안 [IP중복건수, IP내림차순출력]
awk '$4>"[24/Jun/2021:05:03:39]" && $4<"[24/Jun/2021:05:05:38]"' access.log | awk '{ print $1 }' | sort | uniq -c | sort -r | more


      6 192.168.56.1
     20 192.168.56.112

Docker Volume 활용한 파일 연결

docker run -it -v ~/.bash_history:/root/.bash_history --rm centos:8 /bin/bash
ls
echo 'docker volume test' > volume.txt
exit

// 다른 터미널에서 로그 확인 : 컨테이너에서 몇가지 명령 수행 후 exit로 빠져나오면 호스트에 기록됨
cat .bash_history

Docker Volume quota(할당량) 제한

docker run -v /home/jeff/myvolume:/webapp -it --name=vquota ubuntu:14.04 bash
// volume 지정 시 host OS의 전체 용량을 모두 mount

df -h

// OS Level에서 용량을 제한한 image 생성 후 연결할 directory에 mount -> volume으로 지정
// 512MB로 image 생성
dd if=/dev/zero of=temphdd.img count=512 bs=1M
mkfs.ext4 temphdd.img
fdisk -l temphdd.img
mkdir -p /home/jeff/myvolume
mount -o loop temphdd.img /home/jeff/myvolume
df -h
chown -R jeff.jeff /home/jeff/myvolume

docker run -v /home/jeff/myvolume:/webapp -it --name=vquota ubuntu:14.04 bash
df -h


Filesystem      Size  Used Avail Use% Mounted on
overlay          49G   18G   29G  39% /
tmpfs            64M     0   64M   0% /dev
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
shm              64M     0   64M   0% /dev/shm
/dev/loop17     488M  780K  452M   1% /webapp
/dev/sda1        49G   18G   29G  39% /etc/hosts
tmpfs           3.9G     0  3.9G   0% /proc/acpi
tmpfs           3.9G     0  3.9G   0% /proc/scsi
tmpfs           3.9G     0  3.9G   0% /sys/firmware

Volume 활용

docker volume create my-db-volume
docker volume ls

docker run -d --name mydb \
-e MYSQL_ROOT_PASSWORD=password1 \
-e MYSQL_DATABASE=wp \
-v my-db-volume:/var/lib/mysql \
mysql:5.7

//볼륨 조회
docker inspect --type volume my-db-volume
sudo ls /var/lib/docker/volumes/my-db-volume/_data

//볼륨 삭제
docker volume rm my-db-volume

Volume 활용한 데이터 전용 container

docker create -v /data-volume --name=datavol ubuntu:14.04
// create 명령어로 프로세스가 없는 컨테이너 생성

docker run -it --volumes-from datavol ubuntu:14.04
echo 'testing data container' > /data-volume/test-volume1.txt
cat /data-volume/test-volume1.txt
exit //컨테이너 stop

docker run -it --volumes-from datavol ubuntu:14.04
cat /data-volume/test-volume1.txt

echo 'testing data container2' > /data-volume/test-volume2.txt
ls /data-volume/
exit

Container 생성 및 구독 환경설정

  • 복수의 환경변수 설정시 -e 명령 대신 –env-file 명령어로 환경설정파일 생성하여 일괄적으로 등록
nano env_list

----
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=/u01/app/oracle/product/12.2.0/db_1
ORACLE_SID=orcl
PATH=$ORACLE_HOME/bin:$PATH
PS1=[\t@\u-\W]\$
----


docker run -it \
--env-file=env_list \
-w=/u01 \
-v /home/jeff/u01:/u01 \
centos:6 /bin/bash

//설정된 환경변수(set)확인과 작업경로(pwd), 절대경로($PATH) 확인
set
pwd
echo $PATH

docker top webserver6
// Linux의 top과 동일

docker port webserver6

docker rename webserver6 renameserver6

Container 내에서 파일 복사

docker container cp <HOST파일> <Container명>:<Container 내 파일 경로>

docker run -itd --name=test_container centos
docker container cp test_container:/etc/passwd /home/jeff/centos_passwd.txt

// Host의 현재 디렉터리에 있는 local.txt 파일을 text Container의 /tmp/local.txt로 복사
touch local.txt
docker container cp ./local.txt test_container:/tmp/local.txt
docker exec -it test_container ls /tmp

// webserver Container의 /etc/nginx/nginx.conf를  HostOS 경로에 복사
docker run -d -p 7777:80 --name=webserver nginx
docker cp webserver:/etc/nginx/nginx.conf /home/jeff/nginx.conf
docker cp nginx.conf webserver:/etc/nginx/nginx.conf

Container 내에서 파일 변경 이력 확인

  • Container가 image로 부터 생성되었을 때와 달라진 점 확인
docker run -it --name centos6_test centos:6 bash
mkdir docker_test
mkdir docker_test2
useradd docker_user

exit

docker diff centos6_test
// A : 추가된 파일, C : 변경된 파일, D : 삭제된 파일

C /root
A /root/.bash_history
A /docker_test2
C /etc
C /etc/gshadow-
C /etc/passwd-
C /etc/shadow-
C /etc/group
...

Container에서 image 생성

  • Docker Container를 기반으로 Docker image 생성
docker run -it --name webserver8 -d -p 8008:80 nginx
//container 내부의 변동사항을 포함하여 그대로 이미지 생성

docker cp index.html webserver8:/usr/share/nginx/html/index.html
docker ps
docker commit -a "cys" webserver8 webfront:1.0
docker images

docker login
docker tag webfront:1.0 cys779988/webfront:1.0
docker push cys779988/webfront:1.0

docker pull cys779988/webfront:1.0
docker run -it --name webserver1 -d -p 8001:80 cys779988/webfront:1.0
curl localhost:8001

Docker image를 파일로 백업

####

docker container run --name webserver -d -p 9999:80 nginx
docker container export webserver > webserver.tar

tar -tvf webserver.tar
//생성된 tar 파일 상세 확인

sudo scp webserver.tar 192.168.56.112:/home/jeff/webserver.tar

cat webserver.tar | docker import - webap:1.0
//2번 서버에서 webserver.tar 파일을 기반으로 webap:1.0 image 생성

docker images

Image save & load

mkdir save_lab
cd save_lab/
docker image save phpserver:1.0 > phpserver1.tar
docker image save phpserver:1.0 | gzip > phpserver1.tar.gz
docker image save phpserver:1.0 | bzip2 > phpserver1.tar.bz2

ls -lh


-rw-rw-r-- 1 jeff jeff 400M  6월 24 16:03 phpserver1.tar
-rw-rw-r-- 1 jeff jeff 125M  6월 24 16:05 phpserver1.tar.bz2
-rw-rw-r-- 1 jeff jeff 139M  6월 24 16:04 phpserver1.tar.gz


scp phpserver1.tar 192.168.56.112:/home/jeff/phpserver1.tar

T2 -> docker image load < phpserver1.tar
T2 -> docker images
T2 -> docker run -itd -p 8200:80 phpserver:1.0
T2 -> curl localhost:8200

Docker stop, kill

  • docker stop은 graceful shutdown(SIGTERM)
  • docker kill은 force shutdown(SIGKILL)
  • 컨테이너 내부 작업 진행 시 작업 종료를 기다리거나 강제종료하거나 차이
T1 -> docker run -it --name=ubuntu_kill ubuntu:14.04 bash
T2 -> docker kill ubuntu_kill
docker ps -a --format 'table \t\t'
docker run -it --name=kill_container centos:7 bash
ps -ef | grep docker

sudo kill -9 [pid]

host terminal : container는 여전히 start 상태를 유지(session만 kill, container 유지)

MariaDB 분산 파티션 테이블 (Sharding)

-- terminal 5
docker pull mariadb:10.2

-- terminal 1
docker run -d -e MYSQL_ROOT_PASSWORD=koreapass --name=spider mariadb:10.2
docker exec -it spider bash
cat /etc/os-release
apt-get update
apt-get install net-tools && ifconfig
apt-get install -y iputils-ping
ifconfig
eth0: 172.17.0.11

mysql -u root -p < /usr/share/mysql/install_spider.sql
Enter password: (koreapass)

mysql -uroot -p
Enter password: (koreapass)

show engines\G;

-- terminal 2
docker run -d -e MYSQL_ROOT_PASSWORD=koreapass --name=korea1 mariadb:10.1

-- terminal 3
docker run -d -e MYSQL_ROOT_PASSWORD=koreapass --name=korea2 mariadb:10.1

-- terminal 5
docker ps -a

-- terminal 2
docker exec -it korea1 bash
apt-get update
apt-get install net-tools && ifconfig
apt-get install -y iputils-ping
ifconfig
eth0: 172.17.0.13

-- terminal 3
docker exec -it korea2 bash
apt-get update
apt-get install net-tools && ifconfig
apt-get install -y iputils-ping
ifconfig
eth0: 172.17.0.12

-- terminal 4
docker exec -it korea3 bash
apt-get update
apt-get install net-tools && ifconfig
apt-get install -y iputils-ping
ifconfig
eth0: 172.17.0.14


-- terminal 2~4
apt-get install mariadb-plugin-spider
mysql -uroot -p < /usr/share/mysql/install_spider.sql
mysql -uroot -p

show databases;
show engines;

-- terminal 1~4
use mysql;

create user 'spider-user'@'%' identified by 'spiderpass';
grant all on *.* to 'spider-user'@'%' with grant option;
flush privileges;
create database koreaDB;

-- terminal 1
use koreaDB;

create server korea1
    foreign data wrapper mysql
    options(
    host '172.17.0.13',
    database 'koreaDB',
    user 'spider-user',
    password 'spiderpass',
    port 3306
    );
    

create server korea2
    foreign data wrapper mysql
    options(
    host '172.17.0.12',
    database 'koreaDB',
    user 'spider-user',
    password 'spiderpass',
    port 3306
    );
    
select * from mysql.servers;


+-------------+-------------+---------+-------------+------------+------+--------+---------+-------+
| Server_name | Host        | Db      | Username    | Password   | Port | Socket | Wrapper | Owner |
+-------------+-------------+---------+-------------+------------+------+--------+---------+-------+
| korea1      | 172.17.0.11 | koreaDB | spider-user | spiderpass | 3306 |        | mysql   |       |
| korea2      | 172.17.0.13 | koreaDB | spider-user | spiderpass | 3306 |        | mysql   |       |
+-------------+-------------+---------+-------------+------------+------+--------+---------+-------+


create table shard_table
  (id int not null auto_increment
   , name varchar(255) not null
   , address varchar(255) not null
   , primary key(id))
   engine=spider comment='wrapper "mysql", table "shard_table"'
   partition by key(id)
   ( partition korea1 comment = 'srv "korea1"'
   , partition korea2 comment = 'srv "korea2"' );
   
FLUSH TABLES;

-- terminal 2~4
mysql -uroot -p

use koreaDB;
create table shard_table

Categories:

Updated:

Comments