Main reference
Day 46
< Docker Compose >
Docker compose
- 여러 개의 vm(container)에서 여러 개의 docker를 활용해서 다양한 걸 할 수 있는 거
Docker compose - 1) wordpress 실습
yaml - 모든 프로그래밍 언어에 대한 인간친화적 데이터 직렬화 언어
docker-compose.yml 파일 만들어서 아래 내용과 같이 구성했으나
version: '3.9'
services:
DB:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports:
- '8000:80'
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
wordpress_data: {}
service "wordpress" depends on unknown service "db"
라는 에러가 나서 실행이 안된다.
'wordpress' 서비스가 'db' 서비스에 의존하는데, 'db' 서비스가 정의되지 않았다고함
>> 'db' 서비스를 정의하고, 그 다음 'wordpress' 서비스가 'db' 서비스에 의존하도록 설정을 바꿔주도록 해보자
version: '3.9'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports:
- '8000:80'
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
wordpress_data: {}
DB 를 db로 바꿔주었더니 됐다
>> 근데 뒷 elk 실습에서 깨달은 점
깃 레포지토리에 있는 container안에 wordpress 파일이 있는 걸 보아한
저걸 Containers 폴더를 clone받아서 실행하면 안 바꿔줘도 잘 됐을 것 같다... ㅎㅎ
역시나... 이 녀석은 구성이 올바르게 되어있구만
내가 만든 이런저런 Dockerfile과 yaml 파일 등은 필요가 없고
Containers만 가져오면 잘 될 것이다.
docker ps로 확인하면
2개의 컨테이너 실행, 하나는 WordPress이고 하나는 MySQL인 거 확인 가능
docker desktop에서도 확인 가능하다
localhost:8000으로 접속하면
wordpress 설정을 해줄 수 있다
admin 페이지
예제 페이지는 기본으로 이렇게 설정되어 있었다
이렇게 하고 docker-compose down 을 해주면
컨테이너는 내려가고, localhost:8000도 당연히 접속이 끊긴다
복구 해주고 싶으면
다시 docker-compose up -d 해주면 된다
그냥 docker up -d해주면 에러 남
하지만?
Volumes는 남아있다
근데 왜 남아있는가?
Docker 컨테이너와 볼륨은 서로 다른 수명 주기를 가지고 있습니다. 일반적으로 Docker 컨테이너는 실행 중에만 존재하고, 컨테이너가 중지되면 자동으로 제거됩니다. 하지만 볼륨은 컨테이너의 데이터를 보존하고 관리하기 위해 사용되는 Docker의 영구적인 저장소입니다.
볼륨은 데이터를 보존하고 여러 컨테이너 간에 공유할 수 있기 때문에 자동으로 제거되지 않습니다. 이것은 컨테이너를 중지하거나 제거할 때 컨테이너의 데이터가 손실되지 않도록 하기 위한 것입니다.
따라서 Docker 컨테이너와 볼륨은 서로 다른 수명 주기를 가지고 있으며, 볼륨은 명시적으로 삭제되기 전까지 남아 있게 됩니다. 만약 볼륨이 더 이상 필요하지 않다면 별도로 제거해주어야 합니다.
그렇다고 한다.
얘까지 제거해주려면
docker-compose down --volumes
혹은 docker-compose down -v 해주면 된다
복구 한 번 했다가 볼륨까지 제거해준 모습
Docker compose - 2) ELK 실습
이번엔 Containers 폴더를 잘 다운받아주고 거기 안에서
docker-compose up -d를 실행~
그런데?
이미 5000 포트 쓰고 있다고 logstash가 실행이 안된댄다
내가 전에 Elk 사용한 게 있어서 그런갑다 싶어서
컨테이너랑 이미지 전에 썼던걸 지웠는데도 안되길래~
우선 docker-compose down 해주고
docker run -p 5001:5000 logstash:7.16.1
포트넘버 쓰는 걸 바꿔줘봤다
로컬로 접근 가능
Day 47
< Docker 네트워크 보안 >
Docker networking 기본 사항
network와 list를 확인 가능하다
elk 안닫아줬더니 list에 남아있다 ㅎㅎ ;;
inspect -> 네트워크 더 자세히 살펴보기
bridge -> 특정 네트워크 이름에 대한 세부 구성정보 얻기
이름, ID, 드라이버, 연결된 컨테이너 등등
현재는 Containers를 보면 연결된 게 없는 걸 확인할 수 있다
bridge network가 로컬로 범위 지정되었음을 보여줌
= 네트워크가 이 docker host에만 존재한다는 걸 의미
= bridge 드라이버를 사용하는 모든 네트워크에 해당하며, bridge 드라이버는 단일 host 네트워킹을 제공
bridge -> docker desktop 표준설치하면 제공되는 사전 구축된 네트워크
driver이름도 bridge지만 같은 것 아님.
+ Docker network에서 driver란?
Docker 네트워크에서 "driver"는 네트워크의 동작 방식을 결정하는 구성 요소입니다.
간단히 말해, 네트워크 드라이버는 Docker가 컨테이너 간 통신을 관리하는 방식을 정의합니다.
Docker에서는 다양한 종류의 네트워크 드라이버를 제공합니다. 각 드라이버는 특정한 목적에 맞게 설계되어 있으며, 네트워크의 성능, 보안, 격리 등 다양한 측면에서 다른 기능을 제공할 수 있습니다.
일반적으로 사용되는 Docker 네트워크 드라이버에는 다음과 같은 것들이 있습니다:
1. **bridge**: 기본적인 네트워크 드라이버로서, 호스트 시스템의 브리지 네트워크를 사용하여 컨테이너를 연결합니다. 이 드라이버는 기본적으로 Docker에서 사용되며, 컨테이너 간 통신을 가능하게 합니다.
2. **host**: 호스트의 네트워크 인터페이스를 컨테이너와 공유하는 방식으로 동작합니다. 컨테이너는 호스트 시스템의 네트워크와 완전히 동일한 네트워크 환경을 공유하게 됩니다.
3. **overlay**: 여러 호스트에 걸쳐 있는 컨테이너를 위한 네트워크를 제공하는 드라이버입니다. Docker 클러스터에서 사용되며, 다른 호스트 간에 컨테이너 간 통신을 가능하게 합니다.
4. **macvlan**: 물리적인 네트워크 인터페이스를 컨테이너에 직접 연결하는 방식으로 동작합니다. 이 드라이버는 컨테이너에게 고유한 MAC 주소를 할당하여 물리 네트워크와 직접 통신할 수 있게 합니다.
5. **none**: 네트워크를 사용하지 않는 드라이버입니다. 컨테이너는 네트워크를 가지지 않으며, 호스트 시스템과 완전히 격리되어 있습니다.
네트워크 드라이버는 Docker 호스트에서 실행되는 컨테이너 간의 통신 방식을 정의하며, 이를 통해 컨테이너를 네트워크에 연결하고 효율적으로 관리할 수 있습니다.
- 컨테이너 연결
; 기본적으로 bridge네트워크는 새 컨테이너에 할당되므로 네트워크를 지정하지 않으면 모든 컨테이너에 bridge 네트워크가 연결됨
docker run -dt ubuntu sleep infinity
로 새 컨테이너 생성
(sleep : 컨테이너를 백그라운드에서 실행)
그 다음에
docker network inspect bridge
로 확인하면 네트워크 지정안해줘서
방금 배포한 컨테이너가 Containers에 생긴 걸 확인할 수 있음
docker exec -it [컨테이너 ID] bash
해서 컨테이너를 자세히 살펴볼 수 있음
여기에서는 이미지에는 ping할 항목이 없어서
- apt-get update && apt-get install -y iputils-ping
해준 다음에
- ping -c5 www.90daysofdevops.com
이 외부 주소를 핑* 해준다
"ping"은 네트워크에서 다른 장치나 호스트로 패킷을 보내고 응답을 확인하는 네트워크 도구
이를 통해 두 장치 간의 네트워크 연결이 잘 되어 있는지, 연결이 정상적으로 작동하는지를 확인
이렇게 확인할 수 있는데
레퍼런스에서 문제를 해결하기 위해 stop하고 컨테이너 id 찾을 수 있다는데
무슨 문제를 해결하고자 하는건지 모르겠다 **
docker stop [컨테이너 ID]
이렇게 하면 컨테이너 제거됨
- 외부 연결을 위한 NAT 구성하기
nginx 컨테이너 시작하고 Docker host의 포트 8080을 컨테이너 내부의 포트 80으로 매핑하는 실습
(즉, 포트 8080의 Docker host에 도달하는 트래픽은 컨테이너 내부의 포트 80으로 전달됨)
위 명령어로 공식 nginx 이미지를 기반으로 새 컨테이너 시작
하고 컨테이너 상태와 포트 매핑 docker ps로 검토
ports는 0.0.0.0:8000->80/tcp, Names는 web1 인데
이건 모든 host 인터페이스의 8080 포트를 web1 컨테이너 내부의 80 포트에 매핑한다는 뜻
이 포트 매핑을 통해 외부 소스에서 컨테이너의 웹 서비스에 포트 8080의 docker host ip로 액세스 가능
예제는 window 기반이라 wsl 터미널로 이동해서 ip addr 해서 할 수 있다고 하지만
난 일단 window가 아니고 linux 서버 연결하기 귀차너서
그냥 ifconfig로 확인한 후 연결해줬다
저 ip를 가지고 http://[ip]:8000/ 해주면 nginx에 액세스할 수 있음
- 컨테이너 보안
지금까지 배포한 모든 컨테이너는 컨테이너 내 프로세스에 대한 루트 권한 사용함
(= 컨테이너와 host 환경에 대한 모든 관리 액세스 권한이 있다는 뜻
= 많은 보안 취약점 유발할 수 있음)
고로 ! 루트 사용자말고 dockerfile 만들 때 사용자 계정 만들어서 하는 방법
FROM ubuntu:18.04
RUN apt-get update && apt-get upgrade -y
# gid 1000 그룹 생성(basicuser) && uid 1000, 그룹 basicuser의 basicuser라는 유저 생성
RUN groupadd -g 1000 basicuser && useradd -r -u 1000 -g basicuser basicuser
# 이 컨테이너를 통해 실행되는 command는 basicuser의 권한으로 수행
USER basicuser
- docker run --user 1009 ubuntu 명령은 dockerfile에 지정된 모든 사용자를 재정의
- 따라서 컨테이너가 항상 권한이 가장 낮은 사용자 식별자 1009로 실행되며 권한 수준도 가장 낮음
- 이 방법은 이미지 자체의 근본적인 보안 결함을 해결하지 못함 -> 따라서 컨테이너가 항상 안전하게 실행되도록 dockerfile에 루트 사용자가 아닌 사용자를 지정하는 것이 좋음
비공개 레지스트리
- 조직에서 컨테이너 이미지의 비공개 레지스트리를 설정하면 원하는 곳에서 호스팅할 수 있거나 이를 위한 관리형 서비스도 있지만, 대체로 사용자와 팀이 사용할 수 있는 이미지를 완벽하게 제어할 수 있음
- DockerHub는 기준선을 제시하는 데는 훌륭하지만, 이미지 게시자를 많이 신뢰해야 하는 기본적인 서비스만 제공함
린&클린?
"린&클린"은 네트워크 보안 모델 중 하나로, 네트워크 환경을 '린' (clean) 영역과 '클린' (dirty) 영역으로 나누어 관리하는 것을 말합니다. 이 모델은 보안을 강화하고 네트워크 내의 공격 표면을 최소화하기 위해 사용됩니다.
- **린 (Clean) 영역**: 린 영역은 내부 네트워크에서 신뢰할 수 있는 영역으로 간주됩니다. 주로 내부 자원이나 서비스에 접근할 수 있는 영역으로, 일반적으로 내부 네트워크에 위치한 서버, 데이터베이스, 사용자 PC 등이 포함될 수 있습니다. 린 영역은 외부에서의 공격을 최소화하기 위해 강력한 방화벽 정책과 엄격한 접근 제어가 적용되어야 합니다.
- **클린 (Dirty) 영역**: 클린 영역은 외부 네트워크에서 신뢰할 수 없는 영역으로 간주됩니다. 인터넷과 같은 외부 네트워크, 외부 사용자나 시스템이 포함될 수 있습니다. 클린 영역은 린 영역과 격리되어 있어야 하며, 보안적으로 민감한 데이터나 자원에 접근할 수 없도록 구성되어야 합니다.
린&클린 모델은 주로 방화벽, 가상 사설 네트워크 (VLAN), DMZ (Demilitarized Zone), 인증 및 접근 제어 시스템 등을 활용하여 구현됩니다. 이 모델을 사용하면 내부와 외부 네트워크 간의 접근이 엄격히 제어되어 보안을 강화할 수 있습니다.
- 애플리케이션에서 사용하지 않는 리소스가 컨테이너에 필요하지 않은 경우 컨테이너의 크기는 공격 표면 측면에서 보안에 영향을 미칠 수 있음
- latest 이미지를 가져올 때 이미지에 많은 부풀림을 가져올 수 있음
- DockerHub는 리포지토리에 있는 각 이미지의 압축 크기를 표시하는데, docker image를 확인하면 이미지의 크기를 확인할 수 있음
라고 하는데
image의 size를 확인하는 게 보안 측면에서 왜 필요한가?
1. **공격 표면 감소**: 이미지 크기가 작을수록 컨테이너의 공격 표면이 줄어듭니다. 작은 이미지는 컨테이너에 포함된 소프트웨어의 부분 집합만 포함하므로 공격자가 공격할 수 있는 옵션도 줄어듭니다.
2. **보안 취약점 감소**: 이미지가 클수록 내장된 라이브러리, 프레임워크 및 의존성이 많아질 수 있습니다. 작은 이미지를 사용하면 컨테이너에 내장된 소프트웨어의 수가 줄어들어 보안 취약점을 감소시킬 수 있습니다.
3. **오픈 소스 라이브러리 관리**: 작은 이미지를 사용하면 컨테이너에 포함된 오픈 소스 라이브러리의 수가 줄어들어 관리가 쉬워집니다. 또한 작은 이미지를 사용하면 라이브러리의 라이선스 및 보안 업데이트를 쉽게 추적하고 관리할 수 있습니다.
4. **스크립트 및 설정 보안**: 이미지 크기를 줄이면 컨테이너에 포함된 스크립트 및 설정 파일의 수도 줄어듭니다. 작은 이미지를 사용하면 보안 설정 및 스크립트의 유지 관리가 쉬워집니다. 따라서 작은 이미지를 사용하고 이미지 크기를 최소화하는 것은 보안 측면에서 중요합니다. 이미지 크기를 최소화하면 공격 표면이 줄어들고 보안 취약점이 감소하여 보안성을 향상시킬 수 있습니다.
한마디로 이미지 크기를 최소화해서 공격 표면을 줄이기 위해서 그렇다~
린&클린 모델 자체가 네트워크 내의 공격 표면을 최소화하는 거니까 image 사이즈를 압축하고 줄이는 게 중요한 것
Day 48
< Docker의 대안 >
- Podman
- 리눅스 시스템에서 OCI 컨테이너를 개발, 관리, 실행하기 위한 데몬이 없는 컨테이너 엔진
- 컨테이너는 루트 나 루트리스 모드로 실행 가능
- WSL2에서도 실행할 수 있지만 docker desktop만큼 매끄럽진 않고... 컨테이너 실행될 linux VM에 연결할 수 있는 윈도우 원격 클라이언트도 있음
- LXC
- 사용자가 다시 여러 개의 격리된 리눅스 컨테이너 환경을 생성할 수 있게 해주는 컨테이너화 엔진
- Docker와 달리 별도의 시스템 파일과 네트워킹 기능을 갖춘 여러 리눅스 머신을 생성하기 위한 하이퍼바이저 역할
- docker만큼 가볍고 쉽게 배포 가능
- 하지만? docker만큼 이미지 관리 및 배포가 쉽지 않음
- LXC는 오케스트레이션 도구 기능이 없음
- docker보단 저수준의 가상화 기술임
- Containerd
- 독립형 컨테이너 런타임
- docker 컨테이너 서비스 일부였다가 독립됨
- CNCF재단 프로젝트 녀석임
- 기타 Docker 도구
- Rancher, VirtualBox 관련 도구 등
- Gradle, Packer, Logspout, Logstash, Portainer 등이 있음
역할별로 나눠보면
그룹 | 도구 |
빌드 및 관리 | Gradle, Packer |
로그 관리 | Logspout, Logstash |
컨테이너 관리 및 시각화 | Portainer |
'클라우드 > DevOps' 카테고리의 다른 글
[IaC] Terraform (0) | 2024.03.19 |
---|---|
[Red Hat OpenShift] 개념, ROSA Hands-on : cluster 구성 및 autoscale, labeling (5) | 2024.03.19 |
[90DaysOfDevOps] Day 53 - Kubernetes (0) | 2024.03.12 |
[90DaysOfDevOps] Day 49~52 - Kubernetes (1) | 2024.03.12 |
[90DaysOfDevOps] Day 42~45 - Container (Docker) (0) | 2024.03.09 |