도커 이미지
모든 컨테이너는 이미지를 기반으로 생성된다. 도커는
DockerHub
라는 중앙 이미지 저장소에서 이미지를 내려받는다. 누구든 이미지를 내려받을 수 있기때문에 공유가 쉽다.docker [create, run, pull]
의 명령어로 이미지를 내려받을때 도커 허브에서 해당 이미지를 검색한 후 내려받게 된다. 하지만 도커허브에는 누구나 이미지를 올릴 수 있기 때문에 공식 라벨이 없는 이미지는 사용법을 찾을 수 없거나 제대로 동작하지 않을 수 있다.도커이미지 생성
이미지를 내려받아 사용할 수도 있겠지만 실무에서는 특정 개발 환경을 직접 구축한 뒤 이미지를 직접 생성하는 경우가 생긴다.
>>> docker run -it --name commit_test ubuntu:14.04 root@23490f8:/ echo test_first >> first
이미지 구조 이해
Layers
를 확인해보면 같은 이미지 기반으로 레이어가 씌워진걸 확인할 수 있다.이미 사용중인 컨테이너가 존재하는 경우, 이미지를 삭제할 수 없다.
-f
명령어로 강제 삭제하려고 하면 실제 이미지를 삭제하진 않고, 이미지 이름만 삭제한다.이미지 추출
>>> docker load -i ubuntu_14_04.tar
이미지 배포
이미지를 생성했다면 이를 다른 도커 엔진에 배포할 방법이 필요한데, 이때 도커의 이미지 구조인 레이어 형태를 이용하지 않으면(위와 같이 파일로 추출-배포) 매우 비효율적이다.
만든 이미지 파일을 다른 도커 엔진에서 사용하려면 어떻게 해야 할까?
- 공식 도커 허브 이미지 저장소 사용(Public)
- 사설 도커 저장소 사용(Private)
공식 도커 허브 저장소
사설 도커 저장소
도커 사설 저장소를 사용하면 개인 서버에 이미지를 저장할 수 있는 저장소를 만들 수 있다. 이는 컨테이너로 구현되므로 이에 해당하는 도커 이미지가 존재한다. 이 이미지는 도커 허브에서 공식으로 제공하고 있다.
>>> docker run -d --name myregistry \ -p 5000:5000 \ # 기본적으로 저장소 컨테이너는 5000번 포트를 사용 --restart=always \ # 컨테이너가 정지될 때마다 다시 시작하도록 설정 registry:2.6
>>> curl localhost:5000/v2/
사설 저장소에 이미지 push 하기
>>> docker tag my-image-name:0.0 ${DOCKER_HOST_IP}:5000/my-image-name:0.0
>>> docker push 172.17.0.1:5000/my-image-name:0.0 The push refers to repository [172.17.0.1:5000/my-image-name] Get "https://172.17.0.1:5000/v2/": http: server gave HTTP response to HTTPS client
DOCKER_OPTS="--insecure-registry=172.17.0.1:5000"
>>> vim /lib/systemd/system/docker.service [Service] Type=notify # the default is not to use systemd for cgroups because the delegate issues still # exists and systemd currently does not support the cgroup feature set required # for containers run by docker ExecStart=/usr/bin/dockerd -H fd:// \ --containerd=/run/containerd/containerd.sock \ --insecure-registry=172.17.0.1:5000 <추가> ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always >>> systemctl daemon-reload >>> systemctl restart docker
>>> docker push 172.17.0.1:5000/my-image-name:0.0
>>> sudo curl localhost:5000/v2/_catalog {"repositories":["my-image-name"]}
Nginx 서버로 접근 권한 생성
지금까지 방법으로 별도의 인증없이 레지스트리 컨테이너에 이미지를 올릴 수 있다. 도커 허브의 login 과정이 있던 것 처럼 레지스트리 컨테이너에 미리 정의된 계정으로 로그인하도록 설정할 수도 있다.
로그인 인증 기능은 보안을 적용해야 하기 때문에 self-Signed 인증서와 키를 발급해 TLS를 적용한다. 명령어를 차례로 입력해 self-signed ROOT 인증서 파일을 생성한다. 이때 인증서 정보를 입력하는 칸은 전부 공백으로 입력해도 된다.
>>> mkdir certs >>> openssl genrsa -out ./certs/ca.key 2048 # RSA 개인 키를 생성, 생성된 개인 키를 ./certs/ca.key 파일에 저장, 키의 길이를 2048비트로 설정 >>> openssl req -x509 -new -key ./certs/ca.key -days 10000 -out ./certs/ca.crt # openssl ~~: 새로운 인증서 서명 요청(CSR)을 생성, 앞서 생성한 개인 키(ca.key)를 사용하여 CRT를 생성 # -out ~~: 생성된 CSR을 ./certs/ca.crt 파일에 저장
>>> openssl genrsa -out ./certs/domain.key 2048 # RSA 개인 키를 생성, 생성된 개인 키를 ./certs/domain.key 파일에 저장, 키의 길이를 2048비트로 설정 >>> openssl req -new -key ./certs/domain.key -subj /CN=172.17.0.1 -out ./certs/domain.csr # openssl ~~: 새로운 인증서 서명 요청(CSR)을 생성, 앞서 생성한 개인 키(domain.key)를 사용하여 CSR을 생성 # -subj ~~: 요청할 인증서의 주체(도메인 또는 IP)를 설정합니다. CN(Common Name)에 IP 주소 172.17.0.1을 지정 # -out ~~: 생성된 CSR을 ./certs/domain.csr 파일에 저장 >>> echo subjectAltName=IP:172.17.0.1 > extfile.cnf # extfile.cnf라는 파일을 생성하여 subjectAltName 확장을 지정 # subjectAltName: 인증서에 대한 추가적인 이름을 지정, IP 주소(172.17.0.1:5000)를 지정, 브라우저나 도커 클라이언트가 인증서의 CN(Common Name) 외에, 이 IP도 신뢰하도록 만듬 >>> 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 # openssl ~~: 인증서 서명 요청(CSR)을 기반으로 인증서를 생성 # -in ~~: 앞서 생성한 CSR을 입력으로 사용 # -CA ~~: CSR을 서명할 루트 인증서(자체 서명된 인증서)를 지정 # -CAkey ~~: 루트 인증서의 개인 키를 사용하여 서명 # -CAcreateserial: 서명할 때 사용할 일련 번호를 자동으로 생성 # -out ~~: 최종 생성된 인증서를 domain.crt 파일에 저장 # -days ~~: 인증서의 유효 기간을 10,000일로 설정 # -extfile ~~: ubjectAltName 확장을 포함시키기 위해 이전에 생성한 extfile.cnf 파일을 참조
domain.crt
인증서 파일이 생성, 이 파일은 172.17.0.1:5000
에 대한 SSL/TLS 통신에 사용>>> htpasswd -c htpasswd googie >>> mv htpasswd certs/
>>> apt-get install apache2-utils
# vim certs/nginx.conf upstream docker-registry { server registry:5000; } server { listen 443 ssl; server_name 172.17.0.1; 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/ { # 특정 버전의 Docker 클라이언트를 차단하는 설정 if ($http_user_agent ~ "^(docker/1\.(3|4|5(\.[0-9]+)?-dev)|Go ).*$") { return 404; } 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; } auth_basic "registry.localhost"; auth_basic_user_file /etc/nginx/conf.d/htpasswd; add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always; }
docker stop myregistry; docker rm myregistry docker run -d --name myregistry --restart=always registry:2.6 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}}" docker login https://172.17.0.1
>>> cp certs/ca.crt /usr/local/share/ca-certificates/ >>> update-ca-certificates
>>> service docker restart >>> docker start nginx_frontend
>>> docker login https://172.17.0.1
ubuntu@ip-172-31-9-147:~$ sudo curl -u googie:12341234 -X GET https://172.17.0.1/v2/_catalog {"repositories":[]}
>>> docker tag my-image-name:0.0 172.17.0.1/my-image-name:0.0 >>> docker push 172.17.0.1/my-image-name:0.0
>>> sudo journalctl -u docker.service
Sep 23 03:35:14 ip-172-31-9-147 dockerd[98105]: failed to start daemon, ensure docker is not running or delete /var/run/docker.pid: process with PID 97> Sep 23 03:35:14 ip-172-31-9-147 systemd[1]: docker.service: Main process exited, code=exited, status=1/FAILURE
/var/run/docker.pid
파일이 이미 존재>>> sudo systemctl start docker >>> docker push 172.17.0.1/my-image-name:0.0
ubuntu@ip-172-31-9-147:~$ df -h Filesystem Size Used Avail Use% Mounted on /dev/root 6.8G 6.7G 25M 100% / tmpfs 479M 0 479M 0% /dev/shm tmpfs 192M 1.1M 191M 1% /run tmpfs 5.0M 0 5.0M 0% /run/lock /dev/xvda16 881M 133M 687M 17% /boot /dev/xvda15 105M 6.1M 99M 6% /boot/efi tmpfs 96M 12K 96M 1% /run/user/1000 ubuntu@ip-172-31-9-147:~$ sudo docker system prune -a WARNING! This will remove: - all stopped containers - all networks not used by at least one container - all images without at least one container associated to them - all build cache Are you sure you want to continue? [y/N] y Deleted Containers: 236f235f1fb087acb26f0db43036b83c5a5f1fa3e1d0f95d2821b7b88e0bfc6d 8ccaf6f77159657f1c11b765386f817fde2b65bced0ef88646fc13b9c0eb94cc f3bb3b8475cbc7e2d500a7b1228e9db8ec11785f9b70b2e7f4f35a219a4e62e6 7ef102791504220c7bfcd20aa09e94273b011258379ac2104960fce08f3e3bd0 29bbff849f6701077174cece66ddb70dbe1af6264b141e4fac4036c58c3da7e3 ef0f3d09443be92cca0833b7a696aa94a3ad93e1aacae4ea4de84c6b6a34ef97 d58d22201f21960c7d947f156cd6426b24d8c69971b84c23476e1861abeba1df 5434e05a62d15b9fa67105946b6c32f1cacac4cf2fb526dfdf109be6271864e2 b50cd78d9aef0af19b2d9fd1b9cbf485b0a763545d47b29853a41c9bfd4aec3c 4067630328bf240921b71b97889a944a45390417214229d65dc0ec4a548d3662 Deleted Images: untagged: alicek106/fluentd:mongo untagged: alicek106/fluentd@sha256:ae06399ae52a4534908c08a40d1eb7cb29699f4f4008064d311f22e3f97f1086 deleted: sha256:36a0f4961dfb06921712b10752ed778eebae82a4b410cfd399b31428cdebfbb7 deleted: sha256:8db0241b5b5281174c17db096a181475a242dd45de624b1488b15e9e71d0b277 deleted: sha256:55124a9cad3491edf4d62997920c00cc6146f1c2e255616382902b5d7737de9b deleted: sha256:8dacd35f2eb2270caaa9f070ed7e599225266ee8b299278218d84d3218af86d3 deleted: sha256:1e7ddcc04ad73b8433a0d1eaf6a6f05321d6aa159c81329c305c1bdcde0c1007 deleted: sha256:f57bc02c510ff15780116b4aed8dcc7e114409c1f9f5d932201eda2867b497be deleted: sha256:307e0058bc9fa2e0085e5ad806f13a629c1814da025ae5e88e7bee9d627a3896 deleted: sha256:3ca23aab1c9a3b1c07b5950d8e4100883c7e5f7ae68f267eda3b37450f2d735b deleted: sha256:072c6c4dbb92dcadff9f897c2ff88df5c1f6432970d436d16b8222f2fda213cc deleted: sha256:60ab55d3379d47c1ba6b6225d59d10e1f52096ee9d5c816e42c635ccc57a5a2b untagged: nginx:latest untagged: nginx@sha256:04ba374043ccd2fc5c593885c0eacddebabd5ca375f9323666f28dfd5a9710e3 deleted: sha256:39286ab8a5e14aeaf5fdd6e2fac76e0c8d31a0c07224f0ee5e6be502f12e93f3 deleted: sha256:d71f9b66dd3f9ef3164d7023cc99ce344d209decd5d6cd56166c0f7a2f812c06 deleted: sha256:634d30adf8a2232256b2871e268c8f0fdb2c348374cd8510920a76db56868e16 deleted: sha256:f230be3f4e104c7414b7ce9c8d301f37061b4e06afe010878ea55f858d89f7f3 deleted: sha256:c5210c8480131b7dbc5ad8adc425d68cd7a8848ee2e07de3c69cb88a4b8fd662 deleted: sha256:d4f588811a337e0b01da46772d02f7f82ee5f9baff6886365ffb912d455f4f53 deleted: sha256:d73e21a1e27b0184b36f6578c8d0722a44da253bc74cd72e9788763f4a4de08f deleted: sha256:8e2ab394fabf557b00041a8f080b10b4e91c7027b7c174f095332c7ebb6501cb untagged: mongo:latest untagged: mongo@sha256:1a7b344b3ee8b07190fa15555726333e38f5db0a3bfb38b2ce9a1d3973b060be deleted: sha256:81a05b7283523bfe55eb2a90a39789c1bb3bbe95c14efcb4b014ef3e35a5e95e deleted: sha256:2b8e9ac3a426b183e7f8492f6f22c70e2b1d65e1c1a247411eaac3f199ec02cf deleted: sha256:af43f03e41e4b7b8997ccce7b0c9a09f0d82f479c130288ac6b32afb4c1aa236 deleted: sha256:0fa5bf9de901f47195be5f6ed874cbef896c045c3ef83d5f0f452aa1c28877a7 deleted: sha256:5c962e7fd265c034c5959c8199e9b43bec2b112adc26add6336a41259f211383 deleted: sha256:2ea3ae59c4b2a722870d57119064f92fc9c504bede1a1d23df2152bc8e9e4b55 deleted: sha256:bc9a703fd3ce53758af898262ac60c16ce07271d58a7f0cd85ee3ef41e3f5d72 deleted: sha256:48f5e4a39414e7581b1bdb8cdae050d1fee21037e4beb06a3cd5b5f9c2a8b130 deleted: sha256:1b9b7346fee7abbc7f5538eaa23548bd05a45abe8daf6794024be0c8ad7d60bb untagged: 172.17.0.1/my-image-name:0.0 untagged: 172.17.0.1:5000/my-image-name:0.0 untagged: 172.17.0.1:5000/my-image-name@sha256:f63eee3537f580bf42d4ad3da21ab57e01be3f0b1e4719eac480e095f5f9ab5a untagged: googieyu/my-image-name:0.0 untagged: googieyu/my-image-name@sha256:f63eee3537f580bf42d4ad3da21ab57e01be3f0b1e4719eac480e095f5f9ab5a untagged: my-image-name:0.0 deleted: sha256:a9dff8c5b43712a7748ec441abf0f3ff44cc7212561b5313851f5e70b64389fb deleted: sha256:f399d6fa885d6968c1691132405999ea9e799f64de86a429eee12e15d47710fb untagged: mongo:4.4 untagged: mongo@sha256:52c42cbab240b3c5b1748582cc13ef46d521ddacae002bbbda645cebed270ec0 deleted: sha256:d896c071ac6936bcb205f35c17a556b9cabf54733c4e1f4d68cda1348424d65d deleted: sha256:9770d60bea41920e69fd9c7a66d2a029979dd53fc32999611067fb0f9583a31d deleted: sha256:b67f913c5556a12c2fca5f20f1143f66fcd6f44bfff821d489c2153758bfc002 deleted: sha256:2d5fe7b2409e5f94be3b254b2d8f2f63317e57b9ef49b903da48236b7e0bb781 deleted: sha256:5ae8e3694b517a7bb6b76ceccf7d4506a6e0c89f0410e62616578c586d98c535 deleted: sha256:3bfff9e4ddd39aaacc94f04f379fc23f06e655d4e765f3af390f757e36bacd18 deleted: sha256:3f6bf8dcee12c86866a845f8326cef3429004d2466444f9fd5da8c7b943bc6a2 deleted: sha256:02483bf799c5a02a67ea1bcd2a526b01d6f881aaf7947ad74434957990d0efbb deleted: sha256:4a1518ebc26e2e4c26f1c5d78a36d41d87d2fd4a7e4ad37c5f9033f2eb52f26b untagged: ubuntu:14.04 untagged: ubuntu@sha256:64483f3496c1373bfd55348e88694d1c4d0c9b660dee6bfef5e12f43b9933b30 deleted: sha256:13b66b487594a1f2b75396013bc05d29d9f527852d96c5577cc4f187559875d0 deleted: sha256:e08f4f554d8df6b04f441fcdfe207b6314d3c709daa2b1ef66f79bbfb529b8c4 deleted: sha256:c28d0c854fd56736ef4456e3c1c4276a28159751dc13fd1b340bd38d69473f7e deleted: sha256:f2fa9f4cf8fd0a521d40e34492b522cee3f35004047e617c75fadeb8bfd1e6b7 Total reclaimed space: 1.797GB
ubuntu@ip-172-31-9-147:~$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry 2.6 10b45af23ff3 4 years ago 28.5MB nginx 1.9 c8c29d842c09 8 years ago 183MB
ubuntu@ip-172-31-9-147:~$ sudo docker pull googieyu/my-image-name:0.0 0.0: Pulling from googieyu/my-image-name 2e6e20c8e2e6: Pull complete 0551a797c01d: Pull complete 512123a864da: Pull complete e89b1d14b431: Pull complete Digest: sha256:f63eee3537f580bf42d4ad3da21ab57e01be3f0b1e4719eac480e095f5f9ab5a Status: Downloaded newer image for googieyu/my-image-name:0.0 docker.io/googieyu/my-image-name:0.0 ubuntu@ip-172-31-9-147:~$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE googieyu/my-image-name 0.0 a9dff8c5b437 13 days ago 197MB registry 2.6 10b45af23ff3 4 years ago 28.5MB nginx 1.9 c8c29d842c09 8 years ago 183MB
ubuntu@ip-172-31-9-147:~$ sudo docker tag my-image-name:0.0 172.17.0.1/my-image-name:0.0 Error response from daemon: No such image: my-image-name:0.0 ubuntu@ip-172-31-9-147:~$ sudo docker tag googieyu/my-image-name:0.0 172.17.0.1/my-image-name:0.0 ubuntu@ip-172-31-9-147:~$ sudo docker push 172.17.0.1/my-image-name:0.0 The push refers to repository [172.17.0.1/my-image-name] 3176d458de2b: Layer already exists 83109fa660b2: Layer already exists 30d3c4334a23: Layer already exists f2fa9f4cf8fd: Pushed 0.0: digest: sha256:f63eee3537f580bf42d4ad3da21ab57e01be3f0b1e4719eac480e095f5f9ab5a size: 1152 ubuntu@ip-172-31-9-147:~$ sudo curl -u googie:12341234 -X GET https://172.17.0.1/v2/_catalog {"repositories":["my-image-name"]}
googieyu/my-image-name:0.0
으로 존재, 이미지를 푸시할 레지스트리 주소(172.17.0.1/my-image-name:0.0
)로 다시 태그, 이번엔 사설 저장소로 푸시 성공.
댓글