[Docker] 포트포워딩

2023. 2. 27. 01:39Tools/Docker

 

1. 포트포워딩!

 

예시로서 웹서버를 컨테이너에 설치했다고 가정해 보자.

 

 

이 컨테이너가 설치된 운영체제를 우리는 docker host라고 한다.

 

하나의 도커 호스트에는 다수의 컨테이너가 있을 수 있다.

 

도커 호스트를 포함한 컨테이너들은 저마다 독립적인 실행환경을 갖는다.

 

독립적인 실행환경은 독립적인 파일 시스템과 포트(0~65535)를 갖는다.

 

일전에 아파치 웹서버를 라즈베리파이에 설치하고 포트포워딩을 한적 있다.

 

 

2022-07-10 웹서버(apache)_2

라우터 설정을 열어서 포트포워딩을 수행해 집에서 놀고 있는 라즈베리파이로 웹서버 돌리기. 죽은 라즈베리파이 살리기 사실 죽은 지 산지도 모른다. 부팅을 안 한 지 한참이나 되었다. 이전에

ramen4598.tistory.com

이것과 비슷하게 도커 호스트의 포트와 컨테이너의 포트를 연결해 줄 필요가 있다.

 

 

docker run --name 컨테이너이름 --pulbish 호스트포트번호:컨테이너포트 이미지이름
# --publish는 -p로 줄여쓰기도 한다.

docker run의 option을 사용해서 포트포워딩을 할 수 있다.

 

참고로 아파치의 기본 포트 번호가 80번이다.

 

출처 : https://youtu.be/SJFO2w5Q2HI

 


2. 만약 이미 존재하는 컨테이너의 포트를 수정하고 싶을 경우

 

 

How to expose port on live containers? | Jhooq

As DevOps, we often make quite a lot of mistakes and one of the most oversight mistakes we generally do is forget to expose a port for the container. When you realize that you have not exposed any port for the container then you start looking for ways to c

jhooq.com

여기서 제시하는 방법은 총 4가지다.

  1. By updating the desired port entry into config.v2.json and hostconfig.json
  2. Create a new container using the existing container image and then expose the port
  3. Using Docker network - Reversed proxy within the same network
  4. On docker destop(Window 10/MacOS)

 

이 중에서 우리는 1번 방법을 살펴보자.

 

위에 아저씨가 추천한 방식으로 컨테이너의 설정값을 가지고 있는 파일을 수정함으로써 포트를 수정해 보자.

 

도커가 설치된 컴퓨터 어딘가에 위치하고 있는 컨테이너의 설정 파일을 수정할 것이다.

 

  • 만약 이미 Running 중인 컨테이너에 1313 포트를 추가하고자 한다.

 

  • Stop the container.
docker stop <container_name>).

 

  • 우선 컨테이너의 id값을 확인한다.
docker inspect <container_name>
# id값을 확인한다.

 

  • Stop docker service. 도커 종료하세요.

 

  • config.v2.json 파일을 수정한다.
# 1. /var/lib/docker/containers/config.v2.json 파일을 찾는다. (Linux 기준)

vi /var/lib/docker/containers/config.v2.json
# 2. 포트 설정을 수정한다.

...
{
"Config": {
....
"ExposedPorts": {
"80/tcp": {},
"1313/tcp": {} #-> 추가!
},
....
},
"NetworkSettings": {
....
"Ports": {
 "80/tcp": [
 {
 "HostIp": "",
 "HostPort": "80"
 }
 ],
 "1313/tcp": [  # -> 추가 ~
 {
 "HostIp": "",
 "HostPort": "1313"
 }
 ]    # -> ~ 여기까지
 },
....
}

 

  • hostconfig 파일에서 PortBindings를 수정한다.
# 1. /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json (Linux 기준)
vi /var/lib/docker/containers/hostconfig.json
# 2. {
....
 "PortBindings": {
 "80/tcp": [
 {
 "HostIp": "",
 "HostPort": "80"
 }
 ],
 "1313/tcp": [   -> 추가 ~
 {
 "HostIp": "",
 "HostPort": "1313"
 }
 ]   -> ~ 여기까지
 },
.....
}

 

  • Restart docker engine. (에러 없어야 됩니다.)

 

  • Start the container.
docker start <container_name>

 

  • 포트가 추가되었는지 확인한다.
docker ps

 

출처 : https://stackoverflow.com/a/38783433/21194365

출처 : https://jhooq.com/expose-port-on-live-container/#1-by-updating-the-desired-port-entry-into-configv2json-and-hostconfigjson

 


가. linuxkit

 

macOS에서 Docker를 구동하기 위해서 필요한 작고 작은 linux subsystem 정도로 이해하면 된다.

 

다른 운영체제에서 도커를 구동시키기 위해서 필요한 최소한의 linux 커널과 기타 등등을 이식가능하게 한 kit다.

 

암튼 다른 운영체제에서 hostconfig.jsonconfig.v2.json을 수정하기 위해서는 리눅스 가상머신 속으로 들어가야 한다.

 

어떻게 하면 안으로 들어갈 수 있을까? 깡? 까아앙?

 

각 운영체제마다 도커 이미지와 컨테이너 저장소의 위치다.

  • Ubuntu: /var/lib/docker/
  • Fedora: /var/lib/docker/
  • Debian: /var/lib/docker/
  • Windows: C:\ProgramData\DockerDesktop, C:\Program Files\Docker\Docker
  • MacOS: ~/Library/Containers/com.docker.docker/Data/vms/0/

 

저기 안에 들어가면 tty가 있는 경우 아래 명령어로 리눅스 터미널로 들어갈 수 있는데… 난 없네??

 

screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
# Ctrl+a를 누른 다음 k 및 y를 눌러 이 세션을 종료할 수 있습니다.

 

왜 없지?

 

 

Docker for Mac: Could not find ~/Library/Containers/com.docker.docker/Data/vms/0/tty to access volume location

Technical blog about Hadoop, MapR, Hive, Drill, Impala, Spark, OS, Shell, Python, JAVA, Python, Greenplum, etc.

www.openkb.info

 

맥에서 도커 데스크톱에서 tty가 보이지 않는 버그가 있다네용?

 

 

How do I access the Docker CE virtual machine on MacOS BigSur?

I'm running the Docker community edition on MacOS BigSur (11.2.2), and am trying to get into the virtual environment. This article from 2018 says to do $screen ~/Library/Containers/com.docker.docke...

stackoverflow.com

 

이게 백도어로 간주되어 막았는다는 것 같습니다?

 

이쯤 되니 mac에선 그냥 다시 컨테이너 만드는 것이 더 빠르겠다.

 

항상 언제든지 다시 run 할 수 있게 해야 한다.

 

컨테이너가 삭제되면 같이 삭제될 파일들을 잘 관리해야 한다.

 

다시 컨테이너를 만들 때 문제없이 파일들을 옮길 수 있어야 한다.

 

그러기 위해서 컨테이너와 호스트의 파일시스템을 잘 연결해 둘 필요가 있다.

 


나. 음… nsenter요?

 

 

아니 포기할라니깐 방법을 찾았다.

 

docker run -it --rm --privileged --pid=host alpine:edge nsenter -t 1 -m -u -n -i sh
# 또는
docker run -it --privileged --pid=host justincormack/nsenter1

 

??? 이건 뭐냐.. 왜 되냐? 옵션이 너무 많아서 알아먹기 힘들다.

 

해석해 보자…. 새벽 2시인데 …

 

  • -it: 인터랙티브 모드로 실행하고 터미널을 할당합니다.
  • -rm: 컨테이너가 종료되면 컨테이너를 자동으로 삭제된다. (이미지는 남아있다.) 컨테이너를 일회성으로 실행할 때 주로 쓰이는데, 컨테이너가 종료될 때 컨테이너와 관련된 리소스(파일 시스템, 볼륨)까지 깨끗이 제거해 준다.
  • -privileged: 컨테이너에 권한을 부여하여 호스트의 모든 기능에 액세스할 수 있도록 합니다. 컨테이너가 호스트의 namespace에 접근할 수 있도록 권한을 부여한다.
  • --pid=host : 호스트의 프로세스 ID를 사용해서 호스트의 프로세스 ID 네임스페이스에 연결한다.
  • alpine:edge : 용량이 적은 리눅스 이미지 정도로 생각하자.
  • nsenter : namespace enter의 약어. 격리된 namespace에 진입하는 명령어. 뒤에 -t부턴 옵션이다.
  • sh : shell 실행
  • justincormack/nsenter1 : Docker 컨테이너에서 호스트의 namespace에 직접적으로 접근하기 위해 사용되는 이미지입니다. nsenter를 사용하여 호스트와 컨테이너 간의 구분을 허용하지 않고, 호스트의 네임스페이스를 직접적으로 조작할 수 있는 방법을 제공합니다.

 

이 방법들은 보안상 위험할 수 있으므로 주의해서 사용해야 합니다.

 

# 추천 세트!
docker run -it --rm --privileged --pid=host justincormack/nsenter1

 

출처 : https://nulls.co.kr/docker/463

출처 : https://jaeho.tistory.com/entry/docker-nsenter

출처: https://tech.ssut.me/what-even-is-a-container/

 


Docker에서 namespace란

 

네임스페이스(Namespace)는 리눅스 시스템에서 프로세스가 사용하는 리소스의 범위를 나누는 것을 의미합니다.

 

도커에서는 이를 통해 컨테이너 간의 격리를 구현합니다.

 

다음은 도커에서 사용되는 네임스페이스 종류와 간단한 설명입니다.

 

 


나. 기존의 컨테이너 commit해서 이미지로 만들어서 다시 run하기

 

이게 제일 쉽다.

 

별일 없으면 이 방법대로 하자.

 

1. stop running container

docker stop test01

 

 

2. commit the container

docker commit test01 test02 
# test1 컨테이너를 가지고서 test2라는 이미지를 새로 생성한다.

 

 

3. re-run from the committed image

docker run -p 8080:8080 -td test02

 

출처 : https://stackoverflow.com/questions/19335444/how-do-i-assign-a-port-mapping-to-an-existing-docker-container


'Tools > Docker' 카테고리의 다른 글

[Docker] 이미지 배포  (0) 2023.02.27
[Docker] Commit & Dockerfile  (2) 2023.02.27
[Docker] mount  (0) 2023.02.27
[Docker] 컨테이너 안에서 터미널 쓰기!  (0) 2023.02.27
[Docker] 시작하기  (1) 2023.02.27