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
Comments