컨테이너에서 하나의 프로세스 만 실행하는 것이 좋습니다.


79

많은 블로그 게시물과 일반적인 의견에는 "컨테이너 당 하나의 프로세스"라는 말이 있습니다.

이 규칙이 존재하는 이유는 무엇입니까? 모든 프로세스가 작동해야하는 단일 컨테이너에서 ntp, nginx, uwsgi 및 기타 프로세스를 실행하지 않는 이유는 무엇입니까?

이 규칙을 언급하는 블로그 게시물 :


그러나 여전히 Docker를 사용할 수없는 엔터프라이즈 서버의 롤아웃 및 운영을 준비하기 위해 수십 개의 프로세스가 포함 된 매우 "뚱뚱한"컨테이너를 갖는 것이 좋을까요?
Peter

@ J.Doe 아마 괜찮을 것입니다. 컨테이너는 VM과 다르며 작은 응용 프로그램에서도 여러 가지 작은 문제가 있습니다. 엔터프라이즈 롤아웃의 경우 2 년 동안 모두 컨테이너에서 컨테이너를 실행해야합니다.
Evgeny

답변:


65

높은 수준의 건축 및 철학적 주장을 잠시 잊어 버리십시오. 단일 컨테이너의 여러 기능이 의미가있는 몇 가지 중요한 경우가있을 수 있지만 경험적으로 "컨테이너 당 하나의 기능"을 따르는 것이 매우 실용적인 이유가 있습니다.

  • 컨테이너가 단일 기능으로 분리되어 있으면 컨테이너를 수평으로 확장하는 것이 훨씬 쉽습니다. 다른 아파치 컨테이너가 필요하십니까? 다른 곳으로 돌리십시오. 그러나 내 아파치 컨테이너에 DB, cron 및 기타 조각이 들어 있으면 문제가 복잡합니다.
  • 컨테이너 당 단일 기능을 사용하면 컨테이너를 다른 프로젝트 나 목적으로 쉽게 재사용 할 수 있습니다.
  • 또한 개발자가 전체 응용 프로그램 환경이 아닌 프로덕션 환경에서 구성 요소를 풀고 로컬로 문제를 해결할 수 있도록보다 휴대 성이 뛰어나고 예측 가능합니다.
  • 패치 및 업그레이드 (OS 및 응용 프로그램 모두)는보다 격리되고 제어 된 방식으로 수행 될 수 있습니다. 컨테이너에서 여러 비트 앤 밥을 저글링하면 이미지가 커질뿐만 아니라 이러한 구성 요소가 함께 연결됩니다. Z를 업그레이드하기 위해 응용 프로그램 X와 Y를 종료해야하는 이유는 무엇입니까?
    • 위의 코드 배포 및 롤백에도 적용됩니다.
  • 기능을 여러 컨테이너로 분할하면 보안 및 격리 관점에서 더 많은 유연성을 얻을 수 있습니다. 강력한 보안 상태를 유지하거나 PCI와 같은 사항을 준수하기 위해 물리적으로 또는 오버레이 네트워크 내에서 네트워크 수준에서 서비스를 격리 (또는 요구) 할 수 있습니다.
  • stdout / stderr 처리 및 컨테이너 로그에 로그 전송, 컨테이너를 임시로 유지하는 등 기타 사소한 요소

프로세스가 아니라 기능을 말하는 것입니다. 그 언어는 구식입니다. 공식 도커 문서 컨테이너 당 "하나의 관심사"를 추천하는 대신 "하나의 프로세스"라는 말에서 멀어졌습니다 .


1
여전히 스레드에 대한 저수준 논쟁이 여기에 맞는 것 같습니다 ... web.stanford.edu/~ouster/cgi-bin/papers/threads.pdf
jeffmcneill

훌륭하고 포괄적 인 답변!
Rob Wells

이 질문이 OS의 의미에서 실제로 '프로세스'를 의미하지 않는다는 생각입니까-도커 및 관련 저작이 '기능'이라는 단어로 전환하여 명확하게 된 다른 용어를 사용하고 있습니까? 그렇지 않으면 이것이 인정되고 가장 높은 등급의 답변이라는 것을 인정하지만 요청 된 질문에 대한 답변이라고 생각하지 않습니다.

27

며칠 전에 "두 개의 프로세스"컨테이너를 죽인 후, 두 가지 프로세스를 시작한 파이썬 스크립트 대신 두 개의 컨테이너를 사용하게 된 몇 가지 어려움이 있습니다.

  1. Docker는 충돌 컨테이너를 인식하는 데 능숙합니다. 주요 과정이 잘 보이면 그렇게 할 수는 없지만 일부 다른 과정은 끔찍한 죽음으로 사망했습니다. 물론 프로세스를 수동으로 모니터링 할 수는 있지만 왜 다시 구현해야합니까?
  2. 도커 로그는 여러 프로세스가 로그를 콘솔에 뿌릴 때 유용성이 떨어집니다. 다시 프로세스 이름을 로그에 쓸 수 있지만 docker도 그렇게 할 수 있습니다.
  3. 컨테이너에 대한 테스트와 추론은 훨씬 어려워집니다.

이것이 정답입니다.
ClintM

동의했다. 몇 가지 좋은 점에 대한 다른 대답이 있지만 요점은
Brett Wagner

13

권장 사항은 운영 체제 수준 가상화 의 목표와 디자인에서 비롯됩니다.

컨테이너는 자체 사용자 공간 과 파일 시스템 을 제공하여 다른 프로세스를 분리하도록 설계되었습니다 .
이것은 논리적으로 진화 chroot된 파일 시스템으로, 다음 단계는 메모리 덮어 쓰기를 피하고 충돌없이 여러 프로세스에서 동일한 리소스 (예 : TCP 포트 8080)를 사용할 수 있도록 프로세스를 다른 프로세스와 격리하는 것입니다.

컨테이너에 대한 주요 관심은 버전 충돌에 대해 걱정하지 않고 프로세스에 필요한 라이브러리를 패키지화하는 것입니다. 동일한 사용자 공간과 파일 시스템에서 동일한 라이브러리의 두 가지 버전이 필요한 다중 프로세스를 실행하는 경우 각 프로세스에 대해 최소한 LDPATH를 조정하여 적절한 라이브러리를 먼저 찾아야하며 일부 라이브러리는이 방법으로 조정할 수 없습니다. 컴파일 타임에 실행 파일에 경로가 하드 코딩되어 있기 때문에 자세한 내용 은 이 SO 질문 을 참조하십시오.
네트워크 수준에서는 동일한 포트를 사용하지 않도록 각 프로세스를 구성해야합니다.

동일한 컨테이너에서 여러 프로세스를 실행하려면 약간의 조정이 필요하며 하루가 끝나면 동일한 사용자 공간 내에서 여러 프로세스를 실행하고 동일한 파일 시스템 및 네트워크 리소스를 공유하는 것이 좋습니다. 호스트 자체에서?

내가 생각할 수있는 무거운 조정 / 함정에 대한 철저한 목록은 다음과 같습니다.

  • 로그 처리

    볼륨이 마운트되어 있거나 표준 출력에 인터리브되어 있으면 어느 정도 관리 할 수 ​​있습니다. 탑재 된 볼륨을 사용하는 경우 컨테이너에 호스트에 자체 "장소"가 있어야하거나 동일한 컨테이너 두 개가 동일한 리소스를 놓고 싸울 것입니다. stdout에 인터리빙 할 때 docker logs소스를 쉽게 식별 할 수 없다면 분석을 위해 악몽이 될 수 있습니다.

  • 좀비 프로세스주의

    컨테이너가 충돌하는 프로세스 중 하나 인 경우 감독자는 자식을 좀비 상태로 정리하지 못할 수 있으며 호스트 초기화는 절대로 자식을 상속하지 않습니다. 사용 가능한 pid 수 (2 ^ 22이므로 약 4 백만 개)를 다 사용하면 많은 문제가 발생합니다.

  • 우려의 분리

    동일한 컨테이너 내에서 Apache 서버 및 logstash와 같이 분리 된 두 가지를 실행하면 로그 처리가 쉬워 지지만 logstash를 업데이트하려면 Apache를 종료해야합니다. (실제로 Docker의 로깅 드라이버를 사용해야합니다) 현재 세션이 종료되기를 기다리는 것이 정상적입니까? 정상적으로 멈 추면 새 버전을 출시하는 데 시간이 오래 걸리고 시간이 오래 걸릴 수 있습니다. 강제 종료하면 로그 발송자에게 영향을 미치며 IMHO는 피해야합니다.

마지막으로 여러 프로세스가있는 경우 OS를 재생하는 것이며,이 경우 하드웨어 가상화를 사용하면 이러한 요구에 더 잘 맞습니다.


3
나는이 주장들이 설득력이 없다고 생각한다. 여러 컨테이너가있는 프로세스와 호스트에서 실행되는 프로세스에는 큰 차이가 있습니다. 컨테이너의 원래 의도를 설명하는 것은 다소 관련이 있지만 실제로 다중 프로세스 컨테이너를 피해야하는 강력한 이유는 아닙니다. IOW, 당신은 "왜 그렇습니까"로 "왜 그렇습니까?"라고 대답하고 있습니다. 동일한 컨테이너에서 여러 프로세스를 실행하는 것이 매우 편리 할 수 ​​있습니다. 이것이 바로 예입니다. 왜 설명해야합니까?
Assaf Lavie

1
당신은 당신이 염두에 둔 종류의 조정에 대해 자세히 설명하지 않았습니다. 그리고이 조정이 여러 컨테이너를 설정하는 것보다 더 많은 일이라고 주장하지 않았습니다. 구체적인 예를 들어 보자. 일부 주 프로세스와 보조 프로세스를 실행하는 감독자가있는 패키지화 된 도커 이미지가 자주 나타납니다. 이것은 설정하기가 매우 쉽습니다. 용기를 분리하는 것만 큼 쉽습니다. 예 : 앱 및 로그 배송 업체. 따라서, 이것이 왜 그런가에 대한 논쟁은 당신의 책임입니다.
Assaf Lavie

1
BTW, 다중 프로세스 컨테이너에 대해 유효한 주장이 있다고 생각하지만 언급하지 않았습니다. 그러나 어쨌든 분명한 사건이 아닙니다. 어떤 경우에는 하나 이상의 프로세스를 허용하는 것이 완벽하게 허용됩니다. 도대체 매우 인기있는 이미지가 여러 하위 프로세스를 생성합니다. 내가 말하는 것은 절충이 있으며, 당신의 대답은 뉘앙스와 세부 사항이없는 단면 사진을 그립니다.
Assaf Lavie

1
재미있는 ... 우리는 이것에 대해 비슷한 (동일한) 의견을 가지고있는 것 같습니다. 아마도 Critic 배지 를 얻고 자하는 누군가 가 그 배지를 얻기 위해 답을 남용하기로 결정 했기 때문에이 경우에는 무시해도됩니다 .
Pierre.Vriens

1
나는 결론을 "서두르지"않는다. 나는 그것을 무시하는 것이 좋다. 그러나 "당신"은 당신의 대답의 익명의 downvoter가 누구인지에 대해 내 눈으로 본 것에 대해 내 마음을 바꿀 수 없습니다. 어쨌든, 이동할 시간 ...
Pierre.Vriens

6

대부분의 경우와 같이, 그것은 전부 또는 아무것도 아닙니다. "컨테이너 당 하나의 프로세스"의 지침은 컨테이너가 뚜렷한 목적을 제공해야한다는 생각에서 비롯됩니다. 예를 들어 컨테이너는 웹 애플리케이션 Redis 서버 가 아니어야 합니다.

두 프로세스가 단일 모듈 식 기능을 지원하는 한 단일 컨테이너에서 여러 프로세스를 실행하는 것이 합리적입니다.


2

내가 서비스라고 부르는 프로세스, 1 container ~ 1 service . 내 서비스 중 하나라도 실패하면 해당 컨테이너를 스핀 업하고 몇 초 안에 모든 것이 다시 시작됩니다. 따라서 서비스 간에는 종속성이 없습니다. 컨테이너 크기를 200MB 이하 및 최대 500MB 이하로 유지하는 것이 가장 좋습니다 (Windows 기본 컨테이너는 2GB 이상). 그렇지 않으면 가상 머신과 비슷하지만 성능만으로는 충분하지 않습니다. 또한 확장, 서비스 탄력성, 자동 배포 등을 만드는 방법과 같은 몇 가지 매개 변수를 고려하십시오.

또한 환경에 가장 적합한 컨테이너 기술을 사용하여 폴리 고트 환경에서 마이크로 서비스와 같은 아키텍처 패턴을 만드는 방법을 순조롭게 요구합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.