220615_TIL / Docker

신두다·2022년 6월 15일
0

TIL

목록 보기
43/82

Key words

Docker, Docker Hub, Docker Image, Docker/Linux Container, Docker Compose(오늘 직접 해보진 못함)

1. Docker란?

  • 와, 오전에 Docker에 대한 세션 영상 다 듣고 오랜만에 대체 이게 뭔소리인지 멍했었다. 마치 예전에 선형대수할 때 아이겐 벡터, 아이겐 벡터 처음 들었을 때 같았다ㅋㅋㅋ
    • 세션 영상에서 들었던 도커의 정의는 다음과 같다.
      • 도커 = 리눅스에서 돌아가는 프로그램을 PC에서 동작할 수 있도록 제공하는 것. + 쉽고(Dockerfile), 빠르게(Container)
      • 애플리케이션 실행환경을 코드로 작성할 수 있고 OS를 격리화하여 관리하는 기술
      • docker container = Linux Container를 docker라는 회사에서 자체적으로 개발해서 배포해놓은 것!
    • 네에? 뭐라구요? (물론 저 말의 뜻을 더 설명하기는 했다)
  • 근데 오전 QnA 시간에 설명을 다시 잘 듣고 보니 그렇게 어려운 개념은 아니었다.
  • Virtual Machine(가상화) 개념과 비교한 이 그림을 보면 이해하기가 쉽다.
    • 가상화 이전에는 하나의 서버에 하나의 어플리케이션만 올라갈 수 있었다.
    • 리소스가 남는데도 하나의 app밖에 못 쓰는 이 비효율적인 구조를 해결하기 위해 가상화 머신이 등장했다.
    • 가상화머신은 hypervisor 위에 격리된 OS로 나누고, 각각의 OS는 Infrastructure의 리소스를 나눠 먹는다. (맥에서 VMWare 생각하면 된다. 디스크 용량도 나눠먹고 그러잖아)
    • 반면 도커는 하나의 OS만 있고, 그 위에 Container Engine을 통해 여러 다른 개발환경으로 된 앱을 돌릴 수가 있다.
      • (참고로 CPU, 메모리 등이 경영진이라면, Kernel은 비서라고 생각하면 된다고 한다. 사용자가 원하는 요구사항(=프로세스)를 전달하는 역할, 어디에 뭐가 저장되어있는지, 저장하는 것, 경영진의 일정 관리 등을 수행한다. 즉, 하드웨어가 움직일 수 있도록 전달하는 역할을 하는 것인데, 위 그림에서는 컨테이너 엔진이 운영 체제의 커널 역할을 하는 것이다)
    • 그렇기 때문에 가상화 머신은 컨테이너보다 좀 더 느리다. 그렇다면 가상화 머신을 왜 쓰냐?
      • 운영체제부터 격리되어 있기 때문에 보안성에서 상대적으로 더 유리하기 때문이라고 함.
    • 도커만의 특징 - 가장 큰 특징은 어플리케이션에 대한 환경을 Docker는 격리성을 중심으로 한 VM의 관점으로 보다는 Container의 관점에서 빠르고, 개발자와 사용자 커뮤니티를 중심으로 혜택을 제공하는데 있습니다.라고 한다.
    • Docker Hub

도커의 정의를 말하려다가 어째 구조를 말한 것 같으니 다시 정리하고 가자.

즉, 도커란 컴퓨터 개발 환경 자체를 사진 찍는다!고 생각할 수도 있다.

  • 도커를 사용하면 환경 설정을 굉장히 쉽게 할 수 있는 것인데, 예를 들어, 친구네 집 가서 컴퓨터 빌려서 개발하려고 하는데, 그 친구 컴퓨터에는 하나도 세팅이 안되어 있어! 그럴 때 유용하게 쓸 수 있는게 바로 도커다.

쉽게 말해 개발환경 통제가 필요할 때 쓴다고 할 수 있다.

  • 운영체제가 Windows, Linux, Mac OS 다 다른데, 엔지니어가 애플리케이션 개발할 때 전부다 맞춰서 각자 개발해야 한다? 이후 후속 관리까지 다 해야 한다? 너무 어려워!!
  • 그럼 OS만 맞추면 끝이야? 노오~ 각자 app을 컴퓨터에 설치할 때 다른 환경 구성은? 사용자에 따라 달라진다. 이건 어떻게 할거야!
  • 웹 서버 IP, 포트, 방화벽 규칙 등은 어떻게 할거야!

이런 문제들 때문에 개발환경 통제가 필요한거고, 그럴 때 쓸 수 있는게 바로 도커이다. 하나의 컴퓨터에서 여러 개의 컴퓨터를 이용하는 것처럼 하기 위한 것!

  • 참고로 위에서 도커의 정의를 docker container = Linux Container를 docker라는 회사에서 자체적으로 개발해서 배포해놓은 것!라고 얘기했었는데, Linux Container가 바로 위 3가지 문제와 기술을 해결하는 방법으로 개발된 것이고, 그걸 docker라는 회사에서 직접 개발한 것으로 생각하면 된다.

여기서 내가 오늘 했던 질문 하나.

Conda 가상환경이랑 뭐가 다른 건가요?

  • 답변: 콘다는 가상환경만 제공하는데(콘다는 파이썬 프로그램, 라이브러리 등의 버전만 격리시키는 것이다), 도커 컨테이너는 가상환경 뿐 아니라 컴퓨터의 리소스까지 격리가 된다. 범위의 차이로 이해하면 된다.
  • 생각해보니 콘다는 파이썬용 소프트웨어였지! 이걸 기억해냈다면 위와 같은 질문은 하지 않았을 것 같다ㅋㅋㅠ

  • 클라우드 플랫폼
    • 도커를 사용하고 배포할 때 클라우드 플랫폼을 사용할 수 있다.
    • 예를 들어, 내 컴퓨터를 24시간 돌릴 수 없으니까 AWS의 000컴퓨터를 빌려서 도커를 만들 수도 있다.

2. DockerFile, Docker Image, Docker Container, Docker Registry

  • 셋의 관계에 대해선 이 그림을 생각하면 된다.
    • Dockerfile : 소스 코드, 의존성 패키지 등등 사용했던 설정 파일을 버전 관리가 쉽도록 명시한 것. 설명서로 생각하면 되고, image가 무거울 때도 있고 하니까 이 설명서만 보면 누구나 내가 만든 도커를 쓸 수 있도록 한 거라고 생각하면 된다.
    • Image : 서비스 운영에 필요한 서버 프로그램, 소스코드 및 라이브러리, 컴파일된 실행파일을 묶은 형태 (dockerfile을 빌드하면 생성)
    • container : image를 실행한 것
    • registry : 이미지가 모여있는 곳 ex) dockerhub, internal registry(in the corp.)
  • 여기서 잠깐, 프로그램과 프로세스의 차이?
    • 프로세스는 실행 중인 프로그램을 말한다.
    • 프로그램들은 깃헙의 레포지토리에 저장되어 있다.
    • (예전 기술면접 인기 질문이었다고 함)
  • 이와 유사하게 프로세스 = 도커 컨테이너, 프로그램 = 도커 이미지, 깃헙 레포지토리 = 도커 레지스트리-> 레포지토리로 생각할 수 있다.
  • 도커 컨테이너에서 작업했던 것을 밖으로 가져올 수도 있고, 반대로 호스트(내 컴퓨터)에서 작업하던 걸 컨테이너에 집어 넣을 수도 있다.
  • 참고로 도커 컨테이너끼리도 연결할 수 있다. Docker Compose 라고 하는데 오늘 실습해보진 못 했다.

3. Docker CLI

  • Docker는 기본적으로 공식문서가 굉장히 친절하게 되어있다고 한다. 역시나 오늘 실습을 하면서 구글링보다 공식문서에 더 큰 도움을 받았다. 공식문서를 보는 습관을 들이자!
  • 여러 명령어들이 있긴 한데, 아래 실습 코드 옮길 때 다 들어가 있는 거라 굳이 여기에 옮기지는 않겠다. (Docker CP도 마찬가지!)
  • Docker Image 만드는 건 docker container commit 명령을 이용하면 된다.
  • 참고로 이미지로 만들어두면, 이전에 작업했던 내용을 다시 수행하지 않아도 된다는 점과 배포 및 관리가 유용하다는 장점이 있다. (개발환경을 찰칵! 사진을 찍어서 여기저기 주는 거니까!)

4. 실습한 것

오늘은 아래 실습을 해보았다.

문제를 풀며 모든 과정을 주석으로 달며했기 때문에 그대로 옮겨둔다. (일부 정보를 특정할 수 있는 정보는 변경하였음을 밝힌다.)

  • 환경변수를 지정해 Image를 가져와서 실행하고(이미지 -> 컨테이너), 특정 파이썬 파일을 실행해 출력되는 값 확인하기
  • 이미지를 가져와 실행 / 웹 서버와 연결해 게임을 실행하고, 게임 화면 내 특정 단어 확인하기.
  • 2번에서 실행한 컨테이너 안 특정 디렉토리에 있는 파일을 호스트로 가져오기.

[환경변수를 지정해 Image를 가져와서 실행하고(이미지 -> 컨테이너), 특정 파이썬 파일을 실행해 출력되는 값 확인하기]

def n331_part1_1():
    ''' part1_1 에 해당하는 이미지를 실행하고
        출력되는 값을 입력하세요 '''
    return "화이팅"
'''
[과정]
# 참고: 실행할 이미지 Docker Hub에 들어가서 있는지 확인해봄.

# docker image pull
    1. '$ docker pull 이미지_이름:태그'

# docker run - 환경 변수 지정 
    2. $ docker run -e github_username=Username --name contianer_name 이미지_이름:태그 python part1.py 
    
    # 참고
        - 그냥 실행하면 `docker container run --name contianer_name 이미지_이름:태그 python part1.py`
            => KeyError: 'github_username'
        - 궁금증
            1. docker 환경변수의 역할과 세팅 방법은?
                => https://stackoverflow.com/questions/39597925/how-do-i-set-environment-variables-during-the-build-in-docker/63640896#63640896
            2. 필수로 설정해야할 환경 변수 목록(ex. github_username)을 어떻게 확인할 수 있는가?
                => $ docker exec container_name env
                => 근데 container status가 running이어야 확인 가능하다. (위 container run은 기본적으로 바로 exit)
                    => 바로 exited된 container에 대해 docker start/restart를 해도 안되고, docker contauner run할 때 -d 옵션을 줘도 안됨. 
                이건 더 알아봐야할 듯. 내가 뭔가 잘못 하고 있는건가? => 질문 예정.

    # references
        - https://docs.docker.com/engine/reference/commandline/run/ => Search '-env'
        - https://stackoverflow.com/questions/34051747/get-environment-variable-from-docker-container
'''
  • 참고로 주석 중 더 알아봐야할 것 같다고 한 건 코치님께 물어봐 답변을 받아놨다. 나중에 별도로 공부노트 작성해야겠다.

[이미지를 가져와 실행 / 웹 서버와 연결해 게임을 실행하고, 게임 화면 내 특정 단어 확인하기.]

def n331_part1_2():
    ''' part1_2 에 해당하는 이미지를 실행하고
        게임상 오른쪽 3번째 탭에서 시도 횟수를 표현하는 단어를 입력하세요 '''
    return "Lives"
'''
[과정]

# git clone
    1. $ git clone https://github.com/주소

# container run
    2. $ docker container run --name Username --rm -p 818:80 httpd
        => container running
        NOTE!!!! 
            $ docker container run --name Username --rm -p 818:80 이미지_이름:태그 
            으로 해야 함!! 1-3번 문제 풀다가 발견했음. 위에 적어둔 부분은 참고를 위해 그대로 둠.

# change directory 
    3. $ cd SpaceInvaders

# Check server
    4. localhost:818 in WebBrowser
        => checked 'It works!'
# docker copy
    5. $ docker container cp ./ container_name:/usr/local/apache2/htdocs/
        (cf. executed in new terminal - 주의: directory 설정 해당 폴더로 한 상태에서 해야 하는 듯?)

# Final - Check 'localhost:818' in WebBrowser
'''
  • 문제가 정확히는 로컬로 clone해온 게임 실행 파일을 컨테이너에 옮겨서 웹 서버에서 게임을 구동하게 한 것이다.

[2번에서 실행한 컨테이너 안 특정 디렉토리에 있는 파일을 호스트로 가져오기.]

def n331_part1_3():
    ''' 실행한 웹 서버의 /usr/local/apache2 위치에 있는 qeen_track 을 가져오세요
    컨테이너 안에 있는 qeen_track 을 호스트로 가져온 뒤 src 폴더 안에 위치하면 테스트가 통과됩니다. '''
    # Hint : docker container cp

    # **해당 리턴문은 변경하지 마세요 **

    return "src/queen_track"
    
'''
[과정]
# 이 문제는 docker cp에서 어디서 어디로 가져올지 경로 설정하는 것을 상기시키기 위한 문제로 추정된다. (세션 영상에서도 여러 번 강조되었음)

# 가져올 디렉토리로 경로 변경하기 (기존엔 SpaceInvader로 되어있었음)
    $ cd .. 
    $ cd ds-sa-docker 
    $ cd src

# docker 실행
    $ docker container cp container_name:/usr/local/apache2/queen_track ./ 
        => 'queen_track' 없다고 안되네? 'No such container:path: container_name:/usr/local/apache2/queen_track'
        (docker cp 해봐도 똑같이 안됨)

# 'container_name:/usr/local/apache2' 안에 뭐뭐 있는지 확인해보기
    $ docker container inspect container_name => 원하는 대로 안 나옴. 근데 이걸로 env 리스트도 보이네? 필수 입력 env는 구분할 수 없긴 하지만.
    $ docker exec -t -i container_name /bin/bash 로 root@containerid:/usr/local/apache2# 로 들어가서 ls -a 해봐도 안됨. 뭐지?

    $ docker exec container_name ls /usr/local/apache2/ 로 보니까 queen_track 없는데?

#### 1-2에서 image를 httpd로 했었는데 그것 때문인 것 같다. ####
    그러네. 
    $ docker container run --name container_name --rm -p 818:80 이미지_이름:태그 이미지 설정 제대로 했어야했다.
    - 이렇게 했을 때도 파일 목록 잘 확인 됨. $ docker exec container_name ls /usr/local/apache2/
    - src 폴더로 디렉토리 변경해주고, 이거 하면 됨. $ docker container cp container_name:/usr/local/apache2/queen_track ./
    재밌었다!!
'''
  • 이미지 이름 등 정보를 가려둬서 주석이 헷갈릴 수 있을 것 같아 보충 설명을 하자면, 파트2에서 httpd가 아닌 문제에서 주어진 이미지 파일을 가져왔어야 했는데 오늘 세션 실습한 것 그대로 httpd를 가져와 버렸다. 그래서 queen_track이란 걸 찾을 수가 없어 헤맸음.
  • 거의 1-2시간을 헤맸는데, 문제를 잘 읽고, 또 공식문서의 docker container run 명령을 잘 봤으면 틀리지 않을 수 있었다!

여하간 까먹진 않을 듯!


5. 그 외

  • 공인/사설 IP (출처)
    • 처음으로 대중화된 IP 규약인 IPv4가 가질 수 있는 전체 아이피가 46억개 정도 된다. (255^4 => 0~255까지의 숫자 4개가 이어진 형태이므로)
    • 따라서 IP가 부족한 상황을 타개하기 위해 공인, 사설 IP라는 방법이 등장했다!
    • 하나의 공유기가 공인 IP이고, 그 안에 속해있는 애들끼리만 안 겹치도록 사설 IP를 주는 식으로 IP 부족 문제를 해결한 것이다.
      • 데미안 아파트 - 공인 IP, 그 안의 101호 102호 … 가 사설 IP 로 비유 가능
    • 그렇다면, 내 사설 IP에서는 다른 공인IP에 접근할 수 있지만, 반대로 다른 공인에서 내 사설로 접근할 수는 없다! 왜냐면 101동 101호 주소만 주고는 그게 어딘지 찾아갈 수 없으니까!
    • 즉, 절대 고유해야 외부에서 거기로 찾아갈 수 있는데 101동 101호는 여기 아파트 저기 아파트 다 있잖아~
    • 그래서 웹 서비스를 하는 컴퓨터는 공인아이피를 가지고 있다고 한다.
    • (물론 포트포워딩 / DMZ ⇒ 사설아이피에 외부에서 접근할 수 있도록 하는 방법도 있기는 하다고 한다.)
  • 고정/유동 IP (출처 상동)
    • 활용할 수 있는 아이피가 제한되어있기 때문에 쓰는 건 공인/사설 IP와 똑같다.
    • 놀고 있는 컴퓨터에게는 아이피를 걷어가고 쓰고 있는 애들한테만 준다. 유동 아이피는 고정보다 저렴하고 계속 아이피가 바뀌기 때문에 보안도 상대적으로 좋기도 하다고 한다.
    • 유동 아이피로 웹 서비스를 하려면 추가적인 조치가 필요하다. DDNS라는 것.
      • 수시로 바뀌는 유동IP를 인지해서 고정된 도메인으로 연결해주는 것.
    • 그럼에도 IPv4에서는 ip가 부족해질 것으로 예상되며, IPv6가 점차 많이 활용되는 중..
    • (참고로 공인/사설 IP 모두 고정/유동 IP가 될 수 있다고 한다.)

Feeling


  • 오늘 비가 주르륵 주르륵. 기본 과제하고 TIL 정리만 했는데 벌써 밤 11시가 다 되었다. 피곤하다.
  • 오전에 세션영상 듣고 진짜 오늘 큰일나버렸네~ 한 것 치고는, QnA 시간에 코치님이 설명 너무 잘 해주셔서 그런지 재밌게 마무리할 수 있었다. 아 프로세스 까먹기 쉬울 것 같은데 복습 잘해야겠다.
  • 오늘도 수고했다~~
profile
B2B SaaS 회사에서 Data Analyst로 일하고 있습니다.

0개의 댓글