Run The Bridge
docker 2일차 본문
0. docker pull 이 되지 않는 경우
실습할 때, anonmyous로 사용하면 공인 IP를 기준으로 counting 하고, login을 하면 계정 사용자 기준으로 pull을 Counting 한다.
(2021. 07. 19. 월)
# yum install -y epel-release
# yum install -y jq
* 로그인 하지 않았을 때 -anonymous 사용자
# TOKEN_ANONY=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)
* 로그인했을 때 - 각자 계정(username:passwd 부분에 docker hub 계정 입력)
# TOKEN_USER=$(curl --user 'username:passwd' "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)
* 남은 rate-limit 수 확인 요청(익명 사용자) - 6시간에 100회 충전
# curl --head -H "Authorization: Bearer $TOKEN_ANONY" \
https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest
* 남은 rate-limit 수 확인 요청(계정 사용자) - 6시간에 200회 충전
# curl --head -H "Authorization: Bearer $TOKEN_USER" \
https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest
참고: https://subicura.com/k8s/2021/01/02/docker-hub-pull-limit/
1. 컨테이너 로깅( json-file 로그 사용하기)
일일이 컨테이너에 접속하여 로그를 확인하는 일은 번거롭다. → 컨테이너에 있는 host 쪽으로 출력시키자.
도커는 컨테이너의 표준 출력과 표준 에러를 별도의 메타데이터로 저장한다.
백그라운드로 mysql 실행
# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=1234 mysql:5.7
mysql log 확인
# docker logs mysql
비밀번호를 주지 않고 mysql 가동
# docker run -d --name no_passwd_mysql mysql:5.7
# docker log no_passwd_mysql
로그파일이 업데이트될 때마다 확인하기
# docker logs mysql -f
로그파일의 특정 범위만 보고 싶을 때
# docker logs --since 2021-05-22T02:20:33.703259Z mysql
# docker logs --since 2021-05-22T02:20:33.703259Z --until 2021-05-22T02:20:34.679479Z mysql
Docker 기본 경로
# /var/lib/docker/containers
json 로그 파일의 최대 크기 및 파일 개수 설정 --log-opt 옵션(내가 이 정도면 확인하는데 문제가 없겠다)
# docker run -it --log-opt max-size=10k --log-opt max-file=3 --name log-test ubuntu:14.04
syslog 로그
# cd /var/log
# tail -f /var/log/messages
# docker run -d --name syslog_container --log-driver=syslog ubuntu:14.04 echo syslogtest
syslog를 원격 서버의 컨테이너에 저장
<docker01 서버>
# docker run -it -h rsyslog --name rsyslog_server -p 514:514 -p 514:514/udp ubuntu:14.04
root@rsyslog:/# vi /etc/rsyslog.conf // 다음 4개 라인 주석 해제 후 저장
18 $ModLoad imudp
19 $UDPServerRun 514
…
22 $ModLoad imtcp
23 $InputTCPServerRun 514
root@rsyslog:/# service rsyslog restart // rsyslog 서비스 재시작
# tail -f /var/log/syslog
<docker02 클라이언트>
# 사전 세팅
1) vi /etc/sysctl.conf
net.ipv4.ip_forward=1 // 추가 후 저장
2) systemctl restart network
3) sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1 // 값 확인
4) systemctl restart docker // docker 데몬 재시작
# docker run -it --log-driver=syslog --log-opt syslog-address=tcp://192.168.100.150:514 --log-opt tag="mylog" ubuntu:14.04
root@96558e2874ab:/# echo test
1.1. fluentd 로깅
- 오픈 소스 로그 수집 도구
- 도커 컨테이너의 로그를 fluentd를 통해 DataBase에 저장할 수 있음
실습과제 - fluentd와 MongoDB 연동해 컨테이너 로그 저장 (교재 P.68 ~ 71)
- 교재와 다르게 하나의 VM에 컨테이너로 실행
- fluentd - mongodb와 통신은 컨테이너 이름으로
- nginx - fluentd 통신은 교재와 같이 IP로
- fluent.conf 파일은 저자 github(chapter2)에서 다운로드 가능
몽고DB서버에서 몽고DB 컨테이너를 생성한다.
# docker run --name mongoDB -d -p 27017:27017 mongo
fluentd 컨테이너를 생성하기
# docker run -d --name fluentd -p 24224:24224 -v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf -e FLUENTD_CONF=fluent.conf alicek106/fluentd:mongo
도커 서버에서 로그를 수집할 컨테이너를 생성합니다. 이때 --log-driver를 fluentd로 설정하고 --log-opt의 fluentd-address 값에 fluentd 서버 주소를 지정합니다. --log-opt tag를 명시함으로써 로그의 태그를 docker.nginx.webserver로 지정했지만 fluentd의 설정 파일 중 <matchdocker.**>에 맞으므로 몽고DB에 로그로서 저장됩니다.
nginx 이미지를 사용해 컨테이너를 생성해 보자
# docker run -p 80:80 -d --log-driver=fluentd --log-opt fluentd-address=192.168.100.150:24224 --log-opt tag=docker.nginx.webserver nginx
위의 docker run 명령어는 호스트의 80번 포트로 nginx 웹 서버에 접근할 수 있습니다.
몽고DB 서버에서 몽고 DB컨테이너에 들어가 데이터를 확인하기
# docker exec -it mongoDB mongo
> show dbs
> use nginx
> show collections
> db['access'].find()
2. 컨테이너 자원 할당 제한
- 도커는 컨테이너의 메모리, CPU, Block I/O, 컨테이너 저장 공간 등을 제한할 수 있음
- 다수의 컨테이너가 실행 중인 환경에서 컨테이너간 자원 간섭을 줄일 수 있음
- 실제 서비스를 운영하는 단계에서는 컨테이너별 자원 할당이 매우 중요
컨테이너 자원 할당 확인
# docker inspect mycontainer
nginx 기본으로 컨테이너 생성
# docker run -d --name nginx nginx
ngnix 컨테이너에 메모리 1gb로 제한
# docker run -d --memory="1g" --name memory_1g nginx
* 메모리가 부족해지면 컨테이너는 자동으로 종료된다
# docker run -d --name memory_4m --memory="4m" mysql:5.7
# docker ps -a
# docker run -d --name memory_6m --memory="6m" mysql:5.7 → 오류가 나면 10m로 늘리면 된다.
# docker logs memory_6m
컨테이너에 CPU 가중치 설정
# docker run -d --name cpu_1024 --cpu-shares 1024 alicek106/stress stress --cpu 1
# ps aux | grep stress
# docker run -d --name cpu_512 --cpu-shares 512 alicek106/stress stress --cpu 1
# ps aux | grep stress
# docker run -d --name cpuset_1 --cpuset-cpus=1 alicek106/stress stress --cpu 1
# yum -y install epel-release && yum -y install htop
스토리지 드라이버와 컨테이너 저장 공간 제한
아래와 같이 5GB짜리 디스크를 추가하고 reboot 시켜준다.
# mkfs.xfs /dev/sdb
# mkdir /mnt/xfs
# mount /dev/sdb /mnt/xfs -o rw,pquota (pquota가 있어야 공간 제한이 가능하다.)
# vi /etc/docker/daemon.json
{
"storage-driver": "overlay2",
"data-root": "/mnt/xfs"
}
# systemctl restart docker
# docker run -it --storage-opt size=1G centos:7
3. 도커 이미지
- 기본적으로 도커의 공식 이미지 저장소인 도커 허브(Docker Hub)에서 이미지를 다운 받음
- 잘 알려진 애플리케이션의 경우 도커 허브를 통해 공식 이미지를 배포 - Official 라벨이 있음
- 도커 허브에 각자 계정을 생성해 개인 저장소를 사용할 수 있음 - 비용 발생(pull 수 제한)
- 사설 저장소를 만들어 사용할 수도 있음(docker private registry)
기존의 이미지로부터 나만의 이미지 생성
# docker run -it --name commit_test ubuntu:14.04
# echo test_first! >> frist
# exit
# docker commit -a "myname" -m "my first commit" commit_test commit_test:first
# docker images
# docker rm -f 'ubuntu:14.04'
# docker run -it --name commit_test ubuntu:14.04
# docker commit -a "myname" -m "my second commit" commit_test commit_test:second
- 도커는 이미지를 하나의 덩어리로 저장하지 않고 레이어로 나누어 저장
- 동일한 레이어는 중복하여 저장하지 않음
docker 이미지 삭제
# docker images # 확인
# docker rmi commit_test:first # 삭제, '-f' 옵션도 존재
이미지 추출
# docker save
이미지 로드
# docker load
우분투 이미지 저장
# docker save -o ubuntu_14_04.tar ubuntu:14.04
우분투 이미지 로드
# docker load -i ubuntu_14_04.tar
이미지 배포하기
1. 도커 허브를 이용한다.
2. 도커 사설 레지스트리를 사용한다.
새로 만든 이미지를 생성한 Repository에 push 하기
# docker run -it --name commit_container1 ubuntu:14.04
root@18201aae8889:/# echo my first push >> test
root@18201aae8889:/# exit
# docker commit commit_container1 my-image-name:0.0
# docker images
# docker tag my-image-name:0.0 <your_id>/my-image-name:0.0
# docker images
# docker login
# docker push <your_id>/my-image-name:0.0
4. 도커 사설 레지스트리 생성
도커 사설 레지스트리를 사용하면 개인 서버에 이미지를 저장할 수 있는 저장소를 만들 수 있습니다.
# docker run -d --name myregistry -p 5000:5000 --restart=always registry:2.6
→ --restart option: 컨테이너가 종료되었을 때 재시작에 대한 정책을 설정합니다. always는 컨테이너가 정지될 때마다 다시 시작하도록 설정하기 때문에 도커 호스트나 도커 엔진을 재시작하면 컨테이너도 함께 재시작됩니다.
컨테이너 정상동작 확인
# curl localhost:5000/v2/
사설 레지스트리에 이미지 Push 하기
# docker tag my-image-name:0.0 192.168.100.150:5000/my-image-name:0.0
or
/etc/hosts 파일에 [IP] [도메인이름]을 넣은뒤 systemctl restart network 후 docker images로 확인
# # docker tag my-image-name:0.0 anfrhrl5555.co.kr:5000/my-image-name:0.0
레지스트리 컨테이너에 이미지 올리기
# docker push anfrhrl5555.co.kr:5000/my-image-name:0.0
기본적으로 도커 데몬은 HTTPS를 사용하지 않으면 레지스트리 컨테이너에 접근하지 못하도록 설정합니다.
HTTPS를 사용하려면 인증서를 적용해 별도로 설정해야 하는데 지금은 HTTPS를 사용하지 않아도 이미지를 push, pull할 수 있게 다음 옵션을 도커옵션에 추가한 뒤 도커를 재시작합니다.
vi /etc/docker/daemon.json # 파일 생성
{
"insecure-registries": ["anfrhrl5555.co.kr:5000"]
}
# systemctl restart docker
# docker push anfrhrl5555.co.kr:5000/my-image-name:0.0 # 재시도
이미지를 pull할 때도 이미지의 접두어를 레지스트리 컨테이너의 URL로 입력합니다.
# docker pull anfrhrl5555.co.kr:5000/my-image-name:0.0
※ 레지스트리 컨테이너는 생성됨과 동시에 컨테이너 내부 디렉터리에 마운트되는 도커 볼륨을 생성합니다.
push된 이미지 파일은 이 볼륨에 저장되며 레지스트리 컨테이너가 삭제돼도 볼륨은 남아있게 됩니다. 컨테이너를 삭제할 때 볼륨도 함께 삭제하고 싶다면 docker rm 명령어에 --volumes 옵션을 추가합니다.
# docker rm --volumes myregistry
Nginx 서버로 접근 권한 생성('/root 에서 작업')
Self-signed ROOT 인증서(CA) 파일을 생성합니다.
# mkdir certs
# openssl genrsa -out ./certs/ca.key 2048
# openssl req -x509 -new -key ./certs/ca.key -days 10000 -out ./certs/ca.crt → 전부 공백 상관 無
앞에서 생성한 ROOT 인증서로 레지스트리 컨테이너에 사용될 인증서를 생성합니다. 인증서 서명 요청 파일인 CSR 파일을 생성하고 ROOT 인증서로 새로운 인증서를 발급합니다.
# openssl genrsa -out ./certs/domain.key 2048
# openssl req -new -key ./certs/domain.key -subj /CN=192.168.100.150 -out ./certs/domain.csr
# echo subjectAltName = IP:192.168.100.150 > extfile.cnf
# openssl x509 -req -in ./certs/domain.csr -CA ./certs/ca.crt -CAkey ./certs/ca.key -CAcreateserial -out ./certs/domain.crt -days 10000 -extfile extfile.cnf
레지스트리에 로그인할 때 사용할 계정과 비밀번호를 저장하는 파일을 생성합니다.
# yum install httpd-tools || apt-get install apache2-utils
# htpasswd -c htpasswd alicek106
# mv htpasswd certs/
# nginx.conf 설정파일
upstream docker-registry {
server registry:5000;
}
server {
listen 443;
server_name ${DOCKER_HOST_IP};
ssl on;
ssl_certificate /etc/nginx/conf.d/domain.crt;
ssl_certificate_key /etc/nginx/conf.d/domain.key;
client_max_body_size 0;
chunked_transfer_encoding on;
location /v2/ {
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return 404;
}
auth_basic "registry.localhost";
auth_basic_user_file /etc/nginx/conf.d/htpasswd;
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
proxy_pass http://docker-registry;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
}
}
기존에 만든 docker registry 삭제
# docker rm -f myregistry
# docker run -d --name myregistry --restart=always registry:2.6 # 현재는 2.7이 제일 최신버전
# docker run -d --name nginx_frontend -p 443:443 --link myregistry:registry -v $(pwd)/certs/:/etc/nginx/conf.d nginx:1.9
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}"
신뢰할 수 없는 인증서인 Self-signed 인증서를 사용했으므로 도커에서 이를 사용하지 못하도록 에러출력
# docker login https:192.168.100.150
Error response from daemon: Get https://192.168.100.150/v2/: x509: certificate signed by unknown authority
우리가 직접 서명한 인증서를 인증서목록에 추가
# cp certs/ca.crt /etc/pki/ca-trust/source/anchors/
# update-ca-trust
# systemct restart docker
# docker start nginx_frontend
# docker login 192.168.100.150
Username: alicek10656
Password: alicek106
Login Succeeded
컨테이너에 이미지를 push하고 pull하려면 이미지의 접두어를 IP나 도메인 이름으로 설정합니다.
# docker tag my-image-name:0.0 192.168.100.150/my-image-name:0.0
# docker push 192.168.100.150/my-image-name:0.0
'Cloud > docker' 카테고리의 다른 글
docker 5일차 (0) | 2021.07.23 |
---|---|
dockerfile을 이용하여 DB와 python 연동하기 (0) | 2021.07.23 |
docker 4일차 (0) | 2021.07.22 |
docker 3일차 (0) | 2021.07.21 |
docker 1일차 (0) | 2021.07.18 |