Run The Bridge

docker 2일차 본문

Cloud/docker

docker 2일차

anfrhrl5555 2021. 7. 18. 23:44
728x90
반응형

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

uninitialized and password option is not specified 오류가 뜬다.

 

로그파일이 업데이트될 때마다 확인하기
# 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

 

docker 01번
docker02번

 

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()

192.168.100.150 접속
새로고침 로그가 찍힌 모습
docker process 모습


2.  컨테이너 자원 할당 제한

  • 도커는 컨테이너의 메모리, CPU, Block I/O, 컨테이너 저장 공간 등을 제한할 수 있음
  • 다수의 컨테이너가 실행 중인 환경에서 컨테이너간 자원 간섭을 줄일 수 있음
  • 실제 서비스를 운영하는 단계에서는 컨테이너별 자원 할당이 매우 중요
컨테이너 자원 할당 확인
# docker inspect mycontainer

 

nginx 기본으로 컨테이너 생성
# docker run -d --name nginx nginx

'0'은 무한을 뜻한다. 즉, 제한이 없다

ngnix 컨테이너에 메모리 1gb로 제한
# docker run -d --memory="1g" --name memory_1g nginx

1GB로 제한 되어있다.

* 메모리가 부족해지면 컨테이너는 자동으로 종료된다

# 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

overlay 사이즈가 1.0GB로 제한되었다.


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. 도커 사설 레지스트리를 사용한다.

https://hub.docker.com/

 

Docker Hub Container Image Library | App Containerization

We and third parties use cookies or similar technologies ("Cookies") as described below to collect and process personal data, such as your IP address or browser information. You can learn more about how this site uses Cookies by reading our privacy policy

hub.docker.com

 

저장소 생성

 

제목 및 설명 추가

새로 만든 이미지를 생성한 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

728x90
반응형

'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
Comments