Information Security

[Docker] 컨테이너 관리- CLI 본문

STUDY/DevSecOps

[Docker] 컨테이너 관리- CLI

sohexz 2024. 2. 2. 15:08

컨테이너 내부 측정

내부 구조를 가져오기 위해 ubuntu 14.04버전 bash 띄움

$ docker run -it --rm --name=newcontainer ubuntu:14.04 bash

 

 

chroot 혹은 pivot_root : 시스템 영역에서 사용할법한 디렉터리들(opt, proc, root, run, sbin 등)

-> 독립성 보장

 

$ df -h

디바이스의 사용량이나 가용 자원 확인

 

 

컨테이너 격리 기술 정리

 

chroot → 프로세스의 루트 디렉토리를 변경, 격리해 가상의 루트 디렉토리 배정

pivot root → 루트 파일시스템을 바꿔, 컨테이너가 전용 루트 파일시스템을 가지도록 함

mount namespace → namespace 내에 파일 시스템 트리 구성

uts namespace → host와 다른 별개의 hostname을 가지도록 함

pid namespace → pid와 프로세스를 분리(systemd와 분리, 우분투의 1번 프로세스인데 안잡힘)

network namespace → 네트워크 리소스 할당(ip, port, route table, ethernet 등)

ipc namespace → 전용 process table 보유

 

 

$ lsns

격리된 namespace의 목록

 

 

컨테이너의 라이프사이클

  1. create → image의 스냅샷으로 /var/lib/docker 영역 내에 컨테이너가 생성됨
  2. start → process영역에 컨테이너를 생성해 실행 상태로 만들어준다.
  3. stop → process 영역에서 컨테이너를 제거해 종료 상태로 만들어준다.
  4. rm → create로 생성된 스냅샷을 삭제해준다.

run:  create와 start를 한 단계로 묶어준 것

 

컨테이너 운영에 필요한 명령어들

https://docs.docker.com/engine/reference/commandline/container/

 

docker container

 

docs.docker.com

 

컨테이너 운영을 살펴보기 위한 노드 웹서버 구축

 

app.js

const http = require('http');

const server = http.createServer().listen(5678);

server.on('request', (req, res) => {
    console.log('request');
    res.write("HostName: " + process.env.HOSTNAME + "\n");
    res.end();
});

server.on('connection', (socket) => {
    console.log("connected.");
});

 

 

Dockerfile

FROM node:20-alpine3.17
RUN apk add --no-cache tini curl
WORKDIR /app
COPY app.js .
EXPOSE 5678
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "app.js"]

 

 

FROM: 어떤 os와 어떤 프레임워크 위에서 실행시킬지

RUN: 알파인 리눅스이므로 apk로 구동

WORKDIR: /app 이라는 경로를 생성한 다음 cd /app 을 실행

COPY: Dockerfile과 같은 경로의 app.js를 현재경로(. → /app) 에 복사

EXPOSE: 포트바인딩시 컨테이너측의 노출포트가 5678이라는 의미

ENTRYPOINT와 CMD: 내부적으로 그 app.js를 실행해주는 명령어

 

 

$ docker build -t nodeapp:1.0 .

이미지 생성

 

$ docker run -itd -p 5678:5678 --name=nodeapp -h nodeapp nodeapp:1.0

 

--env → 컨테이너의 환경변수 지정

-d, --detach=true → 백그라운드 실행 모드 활성화 + 컨테이너 아이디 등록

-t → TTY(단말 디바이스) 할당(bash창같은거 열어주기)

-i, --interactive → 대화식 모드 열기(컨테이너 내부에 명령어 주고받기)

--name → 실행되는 컨테이너에 이름 부여(미지정시 랜덤한 2단어 조합명으로 부여)

--rm → 컨테이너 종료시 자동으로 컨테이너 제거(stop시 삭제)

--restart → 컨테이너 종료시 적용할 재시작 정책 지정(no, on-failure, on-failure:n(횟수), always)

-v, --volume=호스트경로:컨테이너의경로 → 볼륨설정(볼륨마운트)

-h → 컨테이너의 호스트명 지정(미 지정시 컨테이너 아이디를 호스트명으로 등록)

-p 호스트포트:컨테이너포트, --publish → 호스트포트와 컨테이너포트를 바인딩

-P(대문자), --publish-all=true|false → 컨테이너 내부의 EXPOSE 포트를 랜덤포트와 바인딩

--workdir, -w → 컨테이너 내부의 작업 경로(디렉터리)

 

$ docker top 컨테이너명

컨테이너에서 현재 실행중인 프로세스의 상태 확인

 

$ docker port 컨테이너명

포트정보 확인

 

$ sudo netstat -nlp | grep 조회포트번호

docker-proxy라는 대리포트 조회

 

$ ps -ef | grep 프록시번호

해당 포트바인딩 명령어의 정보가 저장된 위치 확인

 

$ docker stats 컨테이너명

실시간으로 어떻게 자원을 소비하고 있는지 확인

- 컨테이너명을 여럿 적으면 동시에 조회 가능

- 흐름에 따른 갱신을 보고싶지 않다면 --no-stream 옵션 추가

 

 

상태 감시 - 모니터링용 이미지 및 컨테이너 

cadvisor라는 이미지와 컨테이너를 이용하여 전문적으로 docker 상태 확인

 

도커허브가 아닌 gcr에 올라와있는 이 이미지는 볼륨마운트를 해야만 볼 수 있음

$ docker run \
--restart=always \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys/fs/cgroup:/sys/fs/cgroup:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--volume=/dev/disk/:/dev/disk:ro \
--publish=8765:8080 \
--detach=true \
--name=cadvisor \
--privileged \
--device=/dev/kmsg \
gcr.io/cadvisor/cadvisor:latest

메트릭 형태로 실시간 트래픽 확인

 

 

리눅스에서 반복문을 수행시키면 헬스체크를 수행

헬스체크: 서버의 가동 여부를 지속적으로 확인하는 행위

 

$ while true; do curl node서버주소; sleep 초단위; done

sleep으로 딜레이를 주기 때문에 몇 초 마다 한번씩 node서버에 접속

$  docker logs -f 컨테이너명

console.log()로 찍히는 명령어 확인

$ sudo ls -l /var/lib/docker/containers

컨테이너별로 저장된 로그 내역 확인

$ sudo truncate -s 0 /var/lib/docker/contaners/컨테이너아이디-json.log

로그를 비우는 명령어

 

 

log파일의 사이즈 제한

$ sudo vi /etc/docker/daemon.json

파일 수정

{
	"insecure-registries": ["아이피주소"],
	"log-driver": "json-file",
	"log-opts": {
		"max-size": "30m",
		"max-file": "10"
	}
}

 

$ sudo systemctl restart docker.service

재시작 후

$ sudo systemctl status docker.service

갱신내역 확인

 

상태 감시 - 도커 이벤트

$ docker events

마지막 1000개의 이벤트 기록 확인

 

컨테이너 중지 및 시작

$ docker stop nodeapp
$ docker start nodeapp

 

컨테이너 일시정지

$ docker pause nodeapp
$ docker unpause nodeapp