개발/클라우드 엔지니어

우분투에 쿠버네티스 설치하기 2

새벽감성개발자 2024. 1. 18. 09:00
반응형

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를 가지고 있는 이미지

nginx이미지인 a875871 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
정상적으로 이미지가 push된 것을 확인할 수 있다.
웹페이지에서도 정상적으로 이미지가 업로드 된 것을 확인할 수 있다.

 

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

tag가 붙은 것도 다음과 같이 하면 지울 수 있다

 

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에서 오류가 발생했어?

※ 실패 해결 방법

더보기

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에 8.8.8.8을 추가해준다

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

아...ㅋㅋㅋㅋ Dockerfile에 my_ver이 오타가 나서 mv_ver로 구성되어있다.. 이미지를 날리고 새로 만들었다

더보기
hello:1 의 이미지를 삭제하고 새로 만들어줄거다

 

위 코드의 결과를 다음과 같이 확인 할 수 있다.

 

  • 컨테이너 실행 시 -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

ARG가 정상적으로 ENV로 삽입된 것을 확인

  • 이미지 빌드 시점에서 환경변수의 값을 바꾸더라도 컨테이너 실행 시점에서 여전히 환경변수 변경 가능

환경 변수 값이 변경됨을 확인

 

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

docker run -p 5000:80 -d nignx
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

 

--entrypoint를 할때 오류가 발생해서 $ man docker run 으로 찾아보았다
/etc쪽은 접근이 가능한데, /home/master은 접근이 불가능한 문제가 있다. 이건 어떻게 구글링 해야 할 지 몰라서 패스

 

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가 아닌 일반 유저이기 때문에 권한 거부가 뜨는 모습

  • 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

 

반응형