도커 컨테이너에서 여러 프로그램을 실행할 수 있습니까?
데스크톱에서 사용자에게 실행되는 애플리케이션을 배포하는 시점에서 도커에 머리를 싸매고 있습니다.제 애플리케이션은 단순히 플라스크 웹 애플리케이션과 몽고 데이터베이스입니다.일반적으로 VM에 둘 다 설치하고 호스트 포트를 게스트 웹 앱으로 전달합니다.도커를 한번 시도해보고 싶은데 어떻게 두 개 이상의 프로그램을 사용해야 하는지 잘 모르겠습니다.서류에는 ENTERPOINT만 있을 수 있다고 되어있는데 어떻게 몽고와 플라스크를 적용할 수 있나요?아니면 별도의 컨테이너에 있어야 하는 것일까요? 이 경우 서로 어떻게 대화하고 이것이 어떻게 앱 배포를 쉽게 할 수 있을까요?
ENTERPOINT는 하나만 존재할 수 있지만, 해당 대상은 보통 필요한 만큼의 프로그램을 실행하는 스크립트입니다.Supervisor 등을 추가로 사용하여 단일 컨테이너 내에서 여러 서비스 시작을 처리할 수 있습니다.단일 컨테이너 내에서 mysql, apache 및 wordpress를 실행하는 도커 컨테이너의 예입니다.
예를 들어, 단일 웹 응용프로그램에서 사용되는 데이터베이스가 하나 있습니다.그러면 둘 다 하나의 컨테이너에서 실행하는 것이 더 쉬울 것입니다.
둘 이상의 응용프로그램에서 사용되는 공유 데이터베이스가 있는 경우, 데이터베이스는 자신의 컨테이너에서, 응용프로그램은 각각 자신의 컨테이너에서 실행하는 것이 좋습니다.
응용프로그램이 서로 다른 컨테이너에서 실행될 때 서로 통신할 수 있는 방법은 적어도 두 가지가 있습니다.
- 노출된 IP 포트를 사용하고 이를 통해 연결합니다.
- 최근 도커 버전은 링크를 지원합니다.
저는 두 서비스를 동일한 컨테이너에서 실행할 것을 권장했던 이전의 일부 솔루션에 강하게 동의하지 않습니다.권장 사항이 아님이 설명서에 명확히 명시되어 있습니다.
일반적으로 컨테이너 당 하나의 서비스를 사용하여 관심 영역을 분리하는 것이 좋습니다.해당 서비스는 여러 프로세스로 분할될 수 있습니다(예: Apache 웹 서버가 여러 작업자 프로세스를 시작합니다).프로세스가 여러 개여도 상관없지만, 도커의 이점을 최대한 활용하려면 하나의 컨테이너가 전체 애플리케이션의 여러 측면을 담당하는 것은 피해야 합니다.사용자 정의 네트워크 및 공유 볼륨을 사용하여 여러 컨테이너를 연결할 수 있습니다.
슈퍼바이저 또는 유사한 프로그램의 좋은 사용 사례가 있지만 웹 응용 프로그램 + 데이터베이스를 실행하는 것은 그 일부가 아닙니다.
도커 컴포지트를 사용하여 다양한 책임을 지닌 여러 컨테이너를 조정해야 합니다.
여러 개의 서비스를 서로 다른 컨테이너로 분할하는 것이 더 나은 이유에 대한 자세한 설명
이 점에 대한 명백한 오해로 인해 좀 더 자세한 설명을 드리겠습니다.
이를 위해 현대 웹 애플리케이션 개발에서 플라스크 앱 + mongodb 데이터베이스는 실제 복잡성을 입증하기에는 너무 보잘것없기 때문에 좀 더 복잡한 배포 예시를 사용하겠습니다.예를 들어 다음과 같은 경우를 가정해 보겠습니다.
- 플라스크를 이용한 Python 웹 서버
- MongoDB 서버(Postgresl, mariadb 등과 같은 다른 데이터베이스일 수 있음)
- 공유 캐시로서의 redis 서버(memcached와 유사한 솔루션일 수 있음)
- 메시지 큐로 래빗 MQ 서버(다른 메시지 큐일 수 있음)
- 래빗 MQ 서버에서 메시지를 처리할 다른 Python 애플리케이션
- 역방향 프록시 및 SSL 제공자 역할을 할 캐디 인스턴스(Apache, Nginx 등일 수 있음)
그래서 저희는 6가지 서비스가 있습니다.대부분의 현실 세계에서 전문적인 프로젝트는 최소한 그 이상의 복잡성을 가지고 있는 경향이 있기 때문에 이러한 종류의 배치는 요즘 웹 개발에서 새로운 것도 아니고 특별한 것도 아닙니다.
Docker가 여기서 할 수 있는 일은, 그리고 문서에 명확하게 명시된 권장 사용 방법은, 이 6개의 서비스를 각각 별개의 컨테이너로 분리하는 것입니다.
우리가 그렇게 하는 것을 선호하는 이유는 다음과 같습니다.
종속성분리
이러한 서비스는 각각 고유한 종속성을 갖게 됩니다.적어도 이들 중 대부분은 직간접적으로 시스템의 libc에 의존성을 가지고 있으며, 심지어 그 의존성이 때때로 문제가 될 수 있습니다(일부 프로그램은 C 라이브러리의 최신 버전을 사용하도록 패키지화되어 있습니다).그들은 시스템과 관련된 다른 의존성도 분명히 가질 것입니다.그것은 openssl, libxml, libevent 등과 같은 낮은 레벨의 C 라이브러리일 수 있습니다.파이썬, nodejs, ruby 등과 같은 상위 레벨의 도구나...각 서비스는 각 종속성에 대한 다양한 버전만 지원합니다.
각 서비스를 하나의 컨테이너에 설치하려고 "할 수 있다"고 해도 생각보다 더 문제가 많을 것입니다.이미지의 기본 배포 패키지 관리자를 사용해야 할 수도 있습니다. 즉, 각 서비스에 대해 특정 버전을 적용해야 하는 것입니다.예를 들어, postgresql 또는 red 버전은 지정된 Ubuntu 버전에 기본적으로 설치되어 있습니다.타사 리포지토리를 사용하여 선택한 특정 버전을 설치할 수도 있지만 대부분의 Linux/Unix 시스템에서는 대개 호환성이 없는 종속성 문제가 발생하기 때문에 문제가 발생합니다.
불행하게도 이러한 서비스의 특정 버전을 고집하는 것은 요즘에는 그다지 만족스러운 해결책이 아닙니다.Postgresql 버전의 최신 버전을 사용하고 싶을 수도 있습니다. 왜냐하면 Python 프로그램에서 사용하고 싶은 새로운 기능들이 있기 때문입니다.openssl 구현의 보안 문제로 인해 빠른 업그레이드가 필요한 캐디 인스턴스를 업그레이드해야 할 수도 있습니다.
하나의 컨테이너에 사용하는 각 서비스의 특정 버전을 맞추려고 하는 것은 언젠가는 Linux 시스템에 동일한 서비스를 함께 설치하는 것과 완전히 같은 지옥이 될 것입니다.
도커는 이러한 서비스들이 서로 완전히 독립적으로 각각의 종속성을 가질 수 있도록 함으로써 이 문제를 해결할 수 있습니다..docker-compose.yml
파일. 그것은 큰 이점이고 도커를 사용하는 많은 이유 중 하나입니다.
서로 다른 스케일링
이 6가지 서비스를 처음으로 성공적으로 배포하고 이제 웹 프로젝트가 실행되고 있다고 가정해 보겠습니다.이제 새로운 문제가 하나 생겼습니다. 실제 사용자가 애플리케이션을 사용하고 있습니다.그리고 그 실제 사람들은 자원을 사용합니다.CPU, RAM, 디스크 IO, 네트워크 IO, 스토리지 공간 등 구축한 시스템에 제한이 있습니다.이제 응용프로그램을 확장할 수 있어야 합니다.
애플리케이션을 확장하기 위해서는 스택 전체를 복제할 수 없습니다.Python flask 응용 프로그램에 대해 수평으로 확장할 수 있습니다(상태 비저장인 경우). 그러나 Mongodb 인스턴스의 확장은 완전히 다르므로 특정 구성이 필요합니다.Python 애플리케이션을 확장할 경우 로드 밸런싱을 수행하기 위해 캐디 인스턴스를 조정해야 할 수도 있습니다.메모리 내 캐시 서버이기 때문에 redisance를 확장하지 않을 수도 있습니다.메시지 큐에서 메시지를 처리하는 백그라운드 Python 애플리케이션의 크기를 조정하기만 하면 될 수도 있습니다. 이는 애플리케이션의 CPU 사용량이 가장 많은 부분이라고 판단했기 때문입니다.기타...
도커는 각 서비스를 별도의 컨테이너에 정의함으로써 이러한 확장 및 구성 적응을 훨씬 쉽게 수행할 수 있습니다.가장 좋은 경우(모든 경우는 아니지만 많은 경우)에는 이미지에 아무런 영향을 주지 않고 도커 구성을 조정하기만 하면 됩니다.도커 컴포지트를 사용하는 것은 한계가 있기 때문에 Kubernetes와 같은 더 복잡한 오케스트라를 사용함으로써 여러 컴퓨터에서 배포를 확장하는 것도 크게 단순화될 것입니다. 하지만 최소한 그렇게 할 수 있는 해결책이 있을 것입니다.
다양한 스토리지
우리의 MongoDB 인스턴스인 데이터베이스가 여기 있습니다.모든 데이터베이스와 마찬가지로 상태 비저장 서비스에서는 존재하지 않는 특별한 고려 사항이 필요합니다.데이터 지속성, 백업, 아카이브, 데이터 마이그레이션...처리하기에는 그리 사소한 것이 아니라 가장 간단한 실제 사용 사례에도 100% 필요한 작은 것들입니다.
이러한 고려 사항을 처리하기 위해 Docker가 존재하기 전의 과거에는 데이터베이스가 애플리케이션 코드를 실행하는 것과는 다른 컴퓨터에 위치하도록 하는 지침을 마련하는 것이 일반적인 관례였습니다.데이터를 완전히 독립적으로 저장할 수 있는 충분한 이유가 있기 때문에 Docker를 사용할 수 있음에도 불구하고 이러한 관행은 오늘날에도 여전히 존재합니다.
그러나 도커를 데이터베이스용으로 사용하려는 사람들의 경우 비록 개발 단계에 있더라도 별도의 컨테이너에 체계적으로 보관하는 것이 여전히 최선입니다.이를 통해 데이터베이스의 라이프사이클과 스토리지를 명확하게 독립적인 방식으로 관리할 수 있으므로 불필요하고 원치 않는 다른 어떤 상호 작용도 피할 수 있습니다.
개발 중인 Docker와 함께 데이터베이스를 배포하여 쉽게 사용할 수도 있지만, 운영 환경을 위해 AWS RDS와 같은 것을 사용할 수도 있습니다(따라서 Docker를 사용하지 않음).또한 다른 구성을 사용하기만 하면 다른 서비스에 어떠한 부작용도 없이 쉽게 수행할 수 있습니다.
결론
도커를 사용하는 방법을 배울 때는 다음과 같은 두 가지 측면을 숙달해야 합니다.
- 새로운 도커 이미지를 만드는 방법을 배웁니다.다를 .
Dockerfile
파일 및 sh/bash 스크립팅에 대한 많은 정보를 제공합니다. - 실제 사용 사례를 위해 도커를 잘 활용할 수 있도록 기존 도커 컨테이너를 조정하는 방법 학습.합니다를 합니다.
docker-compose
왜냐하면 그것은 아마도 시작을 위한 가장 간단한 도구일 것이지만, 요즘에는 Kubernetes가 이를 위해 점점 더 많이 사용되는 것 같기 때문입니다(또한 훨씬 더 복잡합니다).
이 기술들은 별개의 것이지만 많이 섞여 있습니다.도커 컨테이너를 오케스트레이션하려면 도커 컨테이너가 어떻게 작동하는지 알아야 하며 이를 위해 도커 이미지를 생성할 수 있어야 합니다.그러나 좋은 도커 이미지를 만들려면 이미지의 최종 목표를 이해해야 합니다. 즉, 이미지를 여러 개의 컨테이너로 쉽게 조정할 수 있어야 합니다.
그렇기 때문에 원래 질문을 고려할 때 Python flask 응용 프로그램 + MongoDB 데이터베이스에 대해 이미지를 하나도 만들지 말라는 것이 가장 좋은 조언입니다. 좋은 플라스크 된 파이썬 플라스크 어플리케이션하고 도커입니다 파이썬 플라스크 입니다.docker-compose.yml
Python flask 응용 프로그램과 MongoDB 데이터베이스를 모두 포함하는 파일(공식 MongoDB 이미지 중 하나를 다시 사용).
물론 이를 위해서는 도커 컴포지트를 사용하는 법을 배우고, 공식 MongoDB 이미지를 구성하는 법을 배우며, 환경 변수를 통해 Python flask 애플리케이션에 일부 구성 매개 변수를 주입할 수 있도록 수정해야 합니다.하지만 그런 필수품들은 시간 낭비와는 거리가 멀어요.이는 도커의 진정한 유용성에 도달하기 위한 "올바른" 작업 방식의 전체 부분입니다.
LAMP stack, Mongo DB 및 자체 서비스를 실행해야 하는 비슷한 요구사항이 있었습니다.
도커는 OS 기반 가상화이므로 실행 중인 프로세스를 중심으로 컨테이너를 격리하기 때문에 FOREGROUND에서 실행되는 프로세스가 최소 한 개 필요합니다.
따라서 시작 스크립트를 시작 지점으로 제공하면 시작 스크립트가 확장 도커 이미지 스크립트가 되며, 이 스크립트를 통해 최소한 하나의 포그라운드 서비스가 시작될 때까지 서비스를 스택할 수 있으며, 이 서비스도 끝으로 향합니다.
So my Docker image file has two line below in the very end:
COPY myStartupScript.sh /usr/local/myscripts/myStartupScript.sh
CMD ["/bin/bash", "/usr/local/myscripts/myStartupScript.sh"]
In my script I run all MySQL, MongoDB, Tomcat etc. In the end I run my Apache as a foreground thread.
source /etc/apache2/envvars
/usr/sbin/apache2 -DFOREGROUND
This enables me to start all my services and keep the container alive with the last service started being in the foreground
Hope it helps
UPDATE: Since I last answered this question, new things have come up like Docker compose, which can help you run each service on its own container, yet bind all of them together as dependencies among those services, try knowing more about docker-compose and use it, it is more elegant way unless your need does not match with it.
권장되지 않지만 다음을 사용하여 포그라운드로 2개의 프로세스를 실행할 수 있습니다.wait
. 그냥 다음 내용으로 bash 스크립트를 만드세요. 예start.sh
:
# runs 2 commands simultaneously:
mongod & # your first application
P1=$!
python script.py & # your second application
P2=$!
wait $P1 $P2
In your Dockerfile, start it with
CMD bash start.sh
I would recommend to set up a local Kubernetes cluster if you want to run multiple processes simultaneously. You can 'distribute' the app by providing them a simple Kubernetes manifest.
They can be in separate containers, and indeed, if the application was also intended to run in a larger environment, they probably would be.
A multi-container system would require some more orchestration to be able to bring up all the required dependencies, though in Docker v0.6.5+, there is a new facility to help with that built into Docker itself - Linking. With a multi-machine solution, its still something that has to be arranged from outside the Docker environment however.
With two different containers, the two parts still communicate over TCP/IP, but unless the ports have been locked down specifically (not recommended, as you'd be unable to run more than one copy), you would have to pass the new port that the database has been exposed as to the application, so that it could communicate with Mongo. This is again, something that Linking can help with.
For a simpler, small installation, where all the dependencies are going in the same container, having both the database and Python runtime started by the program that is initially called as the ENTRYPOINT is also possible. This can be as simple as a shell script, or some other process controller - Supervisord is quite popular, and a number of examples exist in the public Dockerfiles.
도커는 방법에 대한 몇 가지 예를 제공합니다.경량 옵션은 다음과 같습니다.
모든 명령을 래퍼 스크립트에 넣고 테스트 및 디버깅 정보를 완성합니다.래퍼 스크립트를 사용자 이름으로 실행합니다.
CMD
이것은 매우 순진한 예입니다.째,트:
#!/bin/bash
# Start the first process
./my_first_process -D
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start my_first_process: $status"
exit $status
fi
# Start the second process
./my_second_process -D
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start my_second_process: $status"
exit $status
fi
# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container will exit with an error
# if it detects that either of the processes has exited.
# Otherwise it will loop forever, waking up every 60 seconds
while /bin/true; do
ps aux |grep my_first_process |grep -q -v grep
PROCESS_1_STATUS=$?
ps aux |grep my_second_process |grep -q -v grep
PROCESS_2_STATUS=$?
# If the greps above find anything, they will exit with 0 status
# If they are not both 0, then something is wrong
if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
echo "One of the processes has already exited."
exit -1
fi
sleep 60
done
다음은 도커 파일입니다.
FROM ubuntu:latest
COPY my_first_process my_first_process
COPY my_second_process my_second_process
COPY my_wrapper_script.sh my_wrapper_script.sh
CMD ./my_wrapper_script.sh
두 개의 컨테이너를 사용하는 것이 바람직하다는 다른 답변에는 동의하지만, 여러 개의 서비스를 하나의 컨테이너에 묶는 것에 마음이 있다면 수퍼바이저와 같은 것을 사용할 수 있습니다.
예를 들어, Hipache에서 포함된 Docker 파일은 supervisor를 실행하며, supervisor.conf 파일은 hipache와 redis-server가 모두 실행되도록 지정합니다.
것 , 를 할 수 .sh -c
를 들어 예를 들어,
CMD sh -c 'mini_httpd -C /my/config -D &' \
&& ./content_computing_loop
도커에서는 프로그램을 실행할 수 있는 두 가지 방법이 있습니다.
- CMD
- 엔트리 포인트
그들 사이의 차이점을 알고 싶다면 여기를 참조해 주세요.
CMD/ENTRYPOINT에는 명령어를 실행할 수 있는 두 가지 형식이 있습니다.
- SHELL 형식
- EXEC 포맷
SHELL 형식:
CMD executable_first arg1; executable_second arg1 arg2
ENTRYPOINT executable_first arg1; executable_second arg1 arg2
이 버전은 셸을 만들고 위의 명령을 실행합니다.여기서는 ";", "&", "|" 등과 같은 셸 구문을 사용할 수 있습니다.따라서 여기서 원하는 수의 명령을 실행할 수 있습니다.실행할 복잡한 명령 집합이 있는 경우 별도의 셸 스크립트를 만들어 사용할 수 있습니다.
CMD my_script.sh arg1
ENTRYPOINT my_script.sh arg1
EXEC 형식:
CMD ["executable", "parameter 1", "parameter 2", …]
ENTRYPOINT ["executable", "parameter 1", "parameter 2", …]
여기서 첫 번째 매개 변수만 실행 파일임을 알 수 있습니다.두 번째 매개 변수부터 모든 것이 해당 실행 파일의 인수/매개 변수가 됩니다.
EXEC 형식으로 여러 명령을 실행하려면 다음과 같이 하십시오.
CMD ["/bin/sh", "-c", "executable_first arg1; executable_second"]
CMD ["/bin/sh", "-c", "executable_first arg1; executable_second"]
위의 명령에서는 명령을 실행하기 위해 shell 명령을 실행 파일로 사용했습니다.이 방법만이 EXEC 형식으로 여러 명령을 실행할 수 있습니다.
다음은 잘못된 것입니다.
CMD ["executable_first parameter", "executable_second parameter"]
ENTRYPOINT ["executable_first parameter", "executable_second parameter"]
CMD ["executable_first", "parameter", ";", "executable_second", "parameter"]
ENTRYPOINT ["executable_first", "parameter", ";", "executable_second", "parameter"]
도커 컨테이너에서 여러 프로그램을 실행할 수 있습니까?
네. 하지만 상당한 위험이 있습니다.
아래는 위와 같은 답변입니다.하지만 세부사항과 권장 해결책을 가지고 있습니다.그런 거에 관심이 있으시다면.
권장되지 않음
경고문.그러나 도커 커뮤니티에서는 여러 서비스에 동일한 컨테이너를 사용하는 것을 권장하지 않습니다.도커 설명서에는 "일반적으로 컨테이너 당 하나의 서비스를 사용하여 문제가 되는 영역을 구분하는 것이 좋습니다."라고 적혀 있습니다. 출처:
• https://archive.ph/3Roa6#selection-307.2-307.100
• https://docs.docker.com/config/containers/multi-service_container/
위의 권장 사항을 무시하기로 선택할 경우 보안이 취약해지고, 불안정해지고, 미래에 고통스러운 성장을 겪게 될 위험이 내포됩니다.
위와 같은 위험성에도 문제가 없는 경우, 여러 서비스를 위해 하나의 컨테이너를 사용하는 설명서는 다음과 같습니다.
• https://archive.ph/3Roa6#selection-335.0-691.1
• https://docs.docker.com/config/containers/multi-service_container/
권장된
보다 강력한 보안과 안정성을 갖춘 컨테이너가 필요하고 향후 확장성과 성능이 향상될 경우 Docker 커뮤니티에서는 다음 두 가지 단계를 권장합니다.
도커 컨테이너 당 하나의 서비스를 사용합니다.결과적으로 여러 개의 용기를 가지게 됩니다.
이 도커 "네트워킹" 기능을 사용하여 원하는 컨테이너를 연결할 수 있습니다.
언급URL : https://stackoverflow.com/questions/19948149/can-i-run-multiple-programs-in-a-docker-container
'programing' 카테고리의 다른 글
.animate()의 콜백이 twice jquery로 호출됩니다. (0) | 2023.09.27 |
---|---|
C/C++ 공유 메모리에서 대기 후 알림 (0) | 2023.09.27 |
요즘 DHTML을 뭐라고 부르나요? (0) | 2023.09.27 |
mysql 인덱스가 메모리에 완전히 맞는지 확인하는 방법 (0) | 2023.09.27 |
Oracle SQL에서 Connect by (0) | 2023.09.27 |