갑자기 정리하게 된 이유?
- 친구랑 같이 스터디를 진행하게 되면서, Docker 관련해서 공유해야 하는 부분이 생겼다.
- 말로만 설명하자니 두서 없이 설명을 하게 되어서 간단하게 정리를 하는 시간을 가지게 되었다.
- 자세하게 보다는 최대한 개념적으로만 설명하여, 흐름을 설명해주고 싶었다.
도커라이징은 뭐야?
- 다른 말로는 containerization이라고도 하지만 결국은 어플리케이션에 필요한 패키지나 디펜던시가 존재하는 파일들을 컨테이너에 작동할 수 있도록 구성하는 작업이라고 설명할 수 있다.
도커라이징을 하는 이유는 무엇인데?
- 이 내용은 컴퓨터와 가상화의 역사 리눅스의 cgroup 등 쭉 말하면, 거의 2시간 동안 나불 댈 수 있을 것 같다. 그나마 개인적인 한 단어로 요약하면 장점은 표준화 라고 생각한다.
- 컨테이너는 프로세스를 격리하고 이식성을 보장한다. 즉 컨테이너를 같은 CPU 아키텍처를 가지고 있는 곳이라면 어디서든지 동작은 보장한다는 것이다 (퍼포먼스나 아키텍처 차이에 따른 이미지 Pull 불가들은 별개)
- 결국은 이렇게 생성된 1개의 이미지들은, 1개의 서비스를 담당하게 되며, 일종의 표준화를 통해 그에 따른 버저닝 전략, 오케스트레이션 전략 등이 생기면서 Docker-compose, ECS, K8S 등등이 생겼다고 개인적으로는 생각한다.
- 따라서 도커라이징을 하면 이식과 확장에 도움이 되기 때문에 사용을 하는 것이 이득이다.
- 잘 사용 안하는 케이스도 있다 (DB 같은 경우)
그럼 어떻게 하는 데?
- 도커 라이징은 어렵지 않다. 결국 이미지 안에 프로세스가 동작할 수 있는 최소 단위를 만족시켜주면 된다.
- 프레임워크 별 기본 전략은 아래와 같은 것 같다.
- 빌드 할 경우
- Jar 파일 빌드 > Base 이미지에 해당 파일 복사 > 실행
- 빌드 안할 경우
- Base 이미지 > 코드 복사 > 패키지 설치 > 실행
- 빌드 할 경우
- 위의 전략에 맞게 알맞은 Docker 파일을 작성하면 된다.
- 각 언어 별 예시 깃 레포 (https://github.com/komljen/dockerfile-examples)
자주 발생하는 문제나 특이사항이 있어?
- 사용하려는 도커 이미지에서 아키텍처를 지원하는지 봐야 한다.
- M1을 사용하면 linux/arm64/v8로 빌드가 되고, 이미지에서 해당 아키텍처를 지원해야 사용할 수 있다.
- 지원하는 아키텍처를 확인하는 방법은 docker repo 사이트에 접근하여 해당 이미지에 linux/arm64가 있는지 확인하면 된다.
- 빌드 할 때에 리눅스에 돌아가게 하려면 플랫폼을 지정하거나
docker buildx
라는 것을 통해 멀티 아키텍처 빌드가 가능하도록 확인하면 좋다 (다만 속도가 좀 느린 편이다. ) - 예시
docker build --platform linux/amd64 -t [ImageName] .
- COPY 명령어를 사용할 때, 상대경로를 사용할 수 없고, 상위 파일과 디렉터리를 사용할 수 없다.
- Dockerfile Docs (https://docs.docker.com/reference/dockerfile/)
- 컨테이너에서 호스트의 서비스로 연결하고 싶을 때 Connection 에러가 뜬다.
- 사용하는 특수 DNS는
host.docker.internal
이다. (Linux는 host-gateway라고 한다)host.docker.internal:host-gateway
로 docker-compose에서 extra_hosts를 지정할 수 있다.
- 해당 URL을 사용하면 호스트에 서비스로 접근하게 된다.
- 출처 https://medium.com/@TimvanBaarsen/how-to-connect-to-the-docker-host-from-inside-a-docker-container-112b4c71bc66)
- localhost:3306으로 접근할 수 있도록 mysql 도커를 띄워놓았다면, 호스트로 접근한 후 다시 mysql 엔드포인트를 호출함으로써 도커에서 도커로 접근할 수 있게 된다.
- 사용하는 특수 DNS는
- Build 시 이전 캐시 정보가 제대로 갱신되지 않아서 발생하는 문제
- 패키지 다운로드 명령어는 달라지지 않는다 ex) apt get install 그러나 외부 패키지가 달라질 경우 다시 다운로드를 받아야 하는 데, 도커 레이어에서는 변화를 명령어가 똑같기 떄문에 변화를 인식하지 못하고 넘어가는 경우가 종종 있다고 한다 (경험은 해본적은 없다.)
- 따라서 no-cache전략을 사용하는 곳도 있다.
좀 더 효율적으로 활용하는 방법이 있어?
- 도커라이징의 꽃은 결국 경량화와 이미지를 만드는 데 소요시간 2가지가 가장 중요하다.
- 대부분의 방법은 도커 레이어 캐싱과 관련이 있으며 캐시 동작 방식은 이전 레이어에서 변경이 발생하면 다음 레이어 모두 재빌드를 수행한다.
- 따라서 최적화 하는 기법은 아래와 같다.
- 논리적인 순서로 커맨드를 배치 (캐싱 동작방식과 관련 있음)
- 불필요한 파일 포함하지 않기 및 레이어 수 최소화 하기
- alpine, slim, Spring이면 jre로만 구성되어 있는 이미지를 베이스 이미지로 사용하기 (굳!)
- 멀티 빌드 수행 (굳!)
- 어플리케이션 빌드를 수행한 이미지를 가져와, 최종단계 연결
- 병렬로 수행이 가능, 최종 레이어에 이전 레이어의 전체를 가져오지 않음
- RUN 명령어를 통해 캐시를 최적화 할 수도 있다.
- 빌드하고 이미지를 만드는 일련의 과정들을 CI 툴(Jenkins) 등을 통해 자동화 할 수 있다.
실제 적용하려면 고려해야하는 사항들은?
- 실환경에 적용한다면 일반적으로 스테이지를 dev, qa, prod로 나누고 생성된 도커이미지로 테스트를 하며 디버깅을 진행하는 데, 도커의 효율성을 높이려면 스테이지 환경 별 변수를 통해 DB와 연결되는 URL등 정보들을 관리할 수 있어야 편함
- DB URL등은 보안이 중요한 사항이기 때문에 Vault나 KMS등을 통해 Key-Value를 암호화하여 사용하여 보안을 확보하는 경우도 많음
- Docker Network등 브릿지 등을 사용하면 어쨌든 도커 내부 네트워크를 한 번 더 타는 것이기 때문에, host 네트워크나 aws에서는 awsvpc를 통해 조금이라도 네트워크 속도를 끌어올리는 경우도 있음
- 네트워크 브릿지의 대역폭과 aws VPC 서브넷 대역폭이 같아버리면 트래픽이 유실됨 (계속 사이클돔)
- 도커 이미지 취약점을 스캔하는 것도 존재하여 도커 이미지 자체의 보안성을 강화하는 경우도 있음
참고자료
728x90
반응형
'Devops 솔루션 > 기타' 카테고리의 다른 글
Cockpit 서버 GUI (0) | 2023.01.03 |
---|---|
[접근제어] Teleport 솔루션 사용 후기 (4) | 2022.08.28 |
[모니터링] RabbitMQ 모니터링 지표 정리 (0) | 2022.04.14 |