4.2 도커 저장소
- 도커 허브(Docker Hub)는 도커 이미지 원격 저장소
4.2.1 도커 허브 계정 만들기
- docker hub : https://hub.docker.com/에 접속해서 계정을 생성
4.2.2 이미지 tag 달기
- tag 명령을 이용하여 기존의 이미지에서 새로운 이름을 부여할 수 있음
- nginx 이미지에 새로운 이름 <USERNAME>/nginx 를 달 예정
# docker tag <OLD_NAME>:<TAG> <NEW_NAME>:<TAG>
docker ps
# CONTAINER ID IMAGE
# 3fc5a81e66db nginx
docker tag nginx:latest master/nginx:1
# tag를 부여할 때 <tag>를 생략할 수도 있다
docker tag nginx master/nginx
4.2.3 이미지 확인
docker images
- 원격 저장소로부터 다운로드 받아 로컬 디스크에 저장된 이미지 리스트를 확인
- 지금까지 사용하고 생성한 이미지 리스트가 출력
- 위에서 다른 이름으로 저장한 이미지도 결국 같은 IMAGE_ID를 가지고 있는 이미지
4.2.4 도커 허브 로그인
- username이 Email Address 이다.. 접속정보이니, 도커 허브에 로그인할 때 기준으로 입력해야 접속이 가능
- Login Succeeded 문구가 보이면 정상적으로 로그인 된 것
4.2.5 이미지 업로드
docker push <USERNAME>/<NAME>
docker push <USERNAME>/master/nginx
- docker push master/nginx 를 하는 경우 다음과 같은 실패 사례를 확인할 수 있다.
※ 실패 해결 방법 : 구글링

오류 상황
denied: requested access to the resource is denied
위에서 dockerhub 페이지에서 봤던 사용자가 설정한 이름인 username넣어줘야 한다.
- 예제에서 만들었던 이미지의 이름은 master/nginx
- 나의 유저의 이름은 newflycloud라고 예시를 들었을때 실제로 작성할 명령어는 다음과 같다
docker push newflycloud/nginx

오류 상황 : newflycloud/nginx 라는 이미지 명이 없음
# docker hub의 username으로 이루어진 nginx 이미지 명을 만들어주고 push한다
docker tag nginx newflycloud/nginx
docker push newflycloud/nginx


4.2.6 이미지 다운로드
docker pull <IMAGE_NAME>
docker pull redis
docker images
- docker run -d redis와 같이 자동으로 이미지를 내려받으면서 실행도 했지만,
- 위의 방식으로 한다면 이미지를 미리 준비할 수 있음
4.2.7 이미지 삭제
docker rmi <IMAGE_NAME>
docker rmi master/nginx
docker images
# 이미지를 삭제해도 다시 다운로드할 수 있다.
docker pull nginx
4.3 도커 파일 작성
- 다른 사용자가 만든 도커 이미지가 아닌, 나만의 도커 이미지 만들때 사용
- 도커 이미지를 사용하기 위해서는 Dockerfile이라는 텍스트 문서를 작성
- Dockerfile에 기반 이미지(base image) 지정
- 원하는 소프트웨어 및 라이브러리를 설치하기 위한 명령을 기술
- 컨테이너 실행 시 수행할 명령을 기술
4.3.1 Dockerfile 기초
hello.py
import os
import sys
my_ver = os.environ["my_ver"]
arg = sys.argv[1]
print("hello %s, my version is %s! % (arg, my_ver))
※ vim hello.py로 열었는데 잘 안보이면 :color morning으로 colorscheme을 변경해서 보면 편하다.
Dockerfile
# Dockerfile
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y curl python-dev
WORKDIR /root
COPY hello.py .
ENV my_ver 1.0
CMD ["python", "hello.py", "guest"]
- FROM : 기반 이미지(base image)를 기반으로 새로운 도커 이미지가 생성됨
- RUN : 사용자가 지정한 명령을 실행하는 지시자
- WORKDIR : 이미지의 작업 폴더 (working directory)를 지정
- COPY : 로컬 호스트에 존재하는 파일을 이미지 안으로 복사하는 지시자
- ENV : 이미지의 환경변수를 지정
- CMD : 이미지 실행 시, default로 실행되면 명령을 지정
4.3.2 도커 빌드
docker build <PATH> -t <IMAGE_NAME>:<TAG>
- 작성한 Dockerfile을 도커 이미지로 변환하기 위해 빌드 명령을 수행
- <PATH>은 Dockerfile이 위치한 directory를 나타냄
- 빌드하는데 시간이 조금 오래 걸림
docker build . -t hello:1
# docker build /home/master -t hello:1
※ 실패 해결 방법
COPY에서 인자가 A 를 B로 옮긴다는 것이기 때문에
COPY hello.py ./ 오타가 났었다. 별 문제 아님
뭔가 삽질하면서 이미지가 <none>인 이미지가 만들어지긴 했다 다른 오류를 하나 만들었으니 해결해놓고 원래 하던 것을 처리해야겠다.

$ docker rmi $(docker images -f "dangling=true" -q) --force
※ 실패 해결 방법 : 링크 참조
[Docker] <none> image야 잘 가~!
도커에서 컨테이너 생성하는데 자꾸 에러가 나서 Dockerfile을 고치고 이미지 다시 생성하고 컨테이너 생성해보고 반복 삽질 중인 평화로운 나날이었다. 그런데 어느 순간 sudo docker images 를 쳐보니
elsboo.tistory.com
- 다음과 같은 방식으로 처리하면 된다

docker.json
{
"dns" : ["127.0.0.X"], ["8.8.8.8"],
"dns-search" : ["example"]
}
systemctl restart docker
# docker을 재시작하면 현재 실행중인 모든 컨테이너가 정지 상태로 간다 참고
docker build --network=host -t hello:1 ./
# docker build --network=host 호스트 네트워크로 진행해서 연결의 일시적 실패가 뜨지 않음
# -t 옵션은 --tag list "name:tag" 포맷 앞에서 쓰인다
# ./ 어떤 경로에 빌드할 건지 정해야 한다

※ 실패 해결 방법 : 구글링
SOLVED: Docker build “Could not resolve ‘archive.ubuntu.com’” apt-get fails to install anything
I was configuring my own Apache server using an ubuntu:latest image and during the process, i encountered an unusual error where i…
medium.com
docker run hello:1
docker run hello:1 echo "hello world!"
docker run hello:1 cat hello.py
docker run hello:1 pwd

- 컨테이너 실행 시 -e 옵션으로 환경변수를 주입할 수 있다
docker run -e KEY=VALUE <REGISTRY>/<IMAGE>:<TAG>
# my_ver 환경변수를 1.5로 수정하여 실행해본다
docker run -e my_ver=1.5 hello:1
4.3.3 Dockerfile 심화
1) ARG
- Dockerfile 안에서 사용할 수 있는 매개변수를 정의
- parameter로 넘겨지는 변수의 값에 따라 생성되는 이미지 내용을 바꿀 수 있음
Dockerfile
# Dockerfile
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y curl python-dev
ARG my_ver=1.0
WORKDIR /root
COPY hello.py .
ENV my_ver $my_ver
CMD ["python", "hello.py", "guest"]
- ARG 지시자를 이용해서 my_ver이라는 변수를 생성
- 이미지 빌드 시 --build-arg 옵션을 이용해서 ARG값을 덮어씌울 수 잇음
docker build . -t hello:2 --build-arg my_ver=2.0
# 위의 방식 대로 build하는 경우 정상 생성되지 않으면 아래의 --network=host 옵션을 사용
docker build --network=host -t hello:2 --build-arg my_ver=2.0 .
docker run hello:2
- 이미지 빌드 시점에서 환경변수의 값을 바꾸더라도 컨테이너 실행 시점에서 여전히 환경변수 변경 가능
2) ENTRYPOINT
- CMD와 유사하나 실행 명령이 override 되지 않고 실행 가능한 이미지를 만듦
Dockerfile
# Dockerfile
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y curl python-dev
WORKDIR /root
COPY hello.py .
ENV my_ver 1.0
ENTRYPOINT ["python", "hello.py", "guest"]
docker build . -t hello:3
docker run hello:3
docker run hello:3 echo "hello"
- echo "hello" 로 파라미터로 전달해도 실행 명령이 override 되지 않음
- 이미지 자체가 실행가능한 바이너리처럼 바뀌었기 때문
Dockerfile
# Dockerfile
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y curl python-dev
WORKDIR /root
COPY hello.py .
ENV my_ver 1.0
ENTRYPOINT ["python", "hello.py"]
- hello:4 이미지를 새로 등록
- 새로운 이미지에서는 hello.py에 들어갈 이름이 없기 때문에 다음과 같은 오류가 나온다.
docker build . -t hello:4
docker run hello:4 new-guest
# new-guest parameter 인자를 전달한다
- new-guest가 실행 명령으로 override 되지 않고 python hello.py의 파라미터로 전달됨을 확인할 수 있다
3) CMD와 ENTRYPOINT의 차이점
- CMD : default command
- 사용자가 이미지를 실행할 때 별다른 명령을 파라미터로 넘겨주지 않으면 default로 실행되는 명령
- 언제든지 override 할 수 있음
- ENTRYPOINT : 이미지를 실행 가능한 바이너리로 만들어주는 지시자
- 이미지 실행 시, 무조건 호출되고 파라미터를 전달하게 되면 해당 파라미터가 그대로 ENTRYPOINT의 파라미터로 전달
4.4 도커 실행 고급
4.4.1 Network
docker run -p <HOST_PORT>:<CONTAINER_PORT> <IMAGE_NAME>
- 외부의 트래픽을 컨테이너 내부로 전달하기 위해서 로컬 호스트 서버와 컨테이너의 포트를 매핑시켜 포워딩함
- 호스트의 5000 port -> container의 80 port와 매핑하는 예제
docker run -p 5000:80 -d nginx
curl localhost:5000
※ 내부/공인 IP의 확인은 다음과 같다
- 내부 IP 확인(NODE내부) : hostname -i / ifconfig
- 공인 IP 확인(NODE밖) : curl ifconfig.co
- 명시적으로 공인 IP가 서버에 할당되어 있을 때만 유효
4.4.2 Volume
docker run -v <HOST_DIR>:<CONTAINER_DIR> <IMAGE_NAME>
- 컨테이너는 휘발성 프로세스이기 때문에 컨테이너 내부의 데이터를 영구적으로 저장 불가
- 컨테이너의 데이터를 지속적으로 보관하기 위해서 볼륨을 사용
- 컨테이너 실행 시, 로컬 호스트의 파일시스템을 컨테이너와 연결하여 필요한 데이터를 로컬호스트에 저장
# 현재 디렉터리를 컨테이너의 nginx 디렉터리와 연결
docker run -p 6000:80 -v $(pwd):/usr/share/nginx/html/ -d nginx
# 현재 디렉터리에 hello.txt 파일을 생성
echo hello! >> $(pwd)/hello.txt
# nginx 내부에서 해당 파일이 보이는지 확인
curl localhost:6000/hello.txt
- 변경사항이 많은 파일의 경우, 컨테이너 내부에 파일을 두지 않고 호스트 서버의 디렉터리를 연결해서 수정
- 컨테이너는 컨테이너 종료 시 저장된 데이터가 사라지지만, 볼륨을 이용하면 삭제되지 않음
4.4.3 Entrypoint
- entrypoint를 이용할 때 --entrypoint 옵션으로 강제로 override 하는 방법
# Dockerfile
FROM ubuntu:18.04
ENTRYPOINT ["echo"]
docker build . -t lets-echo
## 해당 이미지는 echo가 default
docker run lets-echo hello
# hello
# docker run lets-echo = echo
docker run lets-echo cat /etc/password
# == echo "cat /etc/password"
# --entrypoint 옵션을 줘서 ENTRYPOINT = ["echo"] => ["cat"] 으로 변경
docker run --entrypoint=cat lets-echo /etc/password
# == cat /etc/password
4.4.4 User
- 기본적으로 컨테이너의 유저는 root
- 보안상의 이유로 일반 유저를 사용하도록 만들 수 있음
# Dockerfile
FROM ubuntu:18.04
# Ubuntu user create
RUN adduser --disabled-password --gecos "" ubuntu
# container 실행 시 ubuntu로 실행
USER ubuntu
docker build . -t my-user
docker run -it my-user bash
:/$
:/$apt update
# Permission denied
:/$exit
- root 권한으로 만들려면 --user 옵션을 이용해서 명시적으로 유저를 입력 가능
docker run --user root -it my-user bash
:/$ apt update
# > 승인되어 업데이트 완료
:/$ exit
4.4.5 Clean up
# 생성된 모든 컨테이너 삭제
docker rm $(docker ps -aq) -f
docker rmi $(docker images -q) -f
'개발 > 클라우드 엔지니어' 카테고리의 다른 글
5. 쿠버네티스의 기본 (0) | 2024.01.24 |
---|---|
우분투에 쿠버네티스 설치하기 4(TEST) (1) | 2024.01.23 |
우분투에 쿠버네티스 설치하기 1 (0) | 2024.01.17 |
2 컨테이너의 이해 (0) | 2024.01.16 |
1. 쿠버네티스란? (1) | 2024.01.15 |