최근 GitLab docker/nomad 컨테이너가 정의된 메모리 제한(10G)에 도달하여 내 서버가 충돌했습니다. 제한에 도달하면 컨테이너 CPU 시간의 100%가 커널 공간에서 소비됩니다. (컨테이너는 4개의 CPU 코어로 제한됩니다.) 결국 호스트가 잠기고 SSH 연결에 응답하지 않게 됩니다.
커널 로그에는 OOM 종료가 표시되지 않습니다. 또한 disk io의 급증을 발견했지만 설명할 수는 없습니다.
기존 GitLab 데이터와 Nomad 없이 더 작은 예제를 만들어 보았습니다.
config=$(cat <<'EOS'
external_url 'https://xxxxxxxxx'
nginx['listen_port'] = 80
nginx['listen_https'] = false
nginx['proxy_set_headers'] = {
'Host' => '$http_host_with_default',
'X-Real-IP' => '$remote_addr',
'X-Forwarded-For' => '$proxy_add_x_forwarded_for',
'X-Forwarded-Proto' => 'https',
'X-Forwarded-Ssl' => 'on',
'Upgrade' => '$http_upgrade',
'Connection' => '$connection_upgrade'
}
EOS
)
# Started with
docker run --rm -d --memory="5G" \
--name testgitlab \
--publish 10.0.0.1:9001:80 \
-e "GITLAB_SSL=true" \
-e "GITLAB_OMNIBUS_CONFIG=$config" \
gitlab/gitlab-ce:latest
같은 일이 일어났습니다. 시스템 로드가 100%에 도달하면 즉시 컨테이너를 중지했습니다(이번에는 CPU 제한 없음).
처음에는 이것이 GitLab의 버그인 줄 알았으나 내 노트북에서도 동일한 작업을 시도했는데 메모리 제한에 도달하면 OOM 킬러가 즉시 컨테이너 프로세스를 종료했습니다. 이 문제는 GitLab 컨테이너를 실행하는 데 사용한 이전 서버에서도 발생하지 않았습니다.
이 문서에 언급된 모든 시스템에는 특별한 Docker 설정이 없으며 스와핑이 비활성화되어 있으며 네트워크 하위 시스템의 sysctl 설정만 수정됩니다.
- 이전 서버: Debian 10
- 버스터 백포트의 커널(5.10.0-0.bpo.9-amd64)
- 파일 시스템: md-raid 1의 btrfs(2x nvme ssd)
- 현재 서버: 데비안 11
- 불스아이 커널(5.10.0-9-amd64)그리고불스아이 백포트(5.14.0-0.bpo.2-amd64) 커널. 두 코어 모두에 문제가 발생합니다.
- 파일 시스템: md-raid 1의 lvm에 있는 btrfs(2x nvme SSD)
- 내 노트북: 아치
- 커널: 5.15.5-arch1-1
- 파일 시스템: lvm의 ext4, ssd의 nvme
GitLab이 메모리 제한에 도달할 때 호스트 정지를 방지하는 방법은 무엇입니까? 왜 현재 서버에만 영향을 미치나요?
고쳐 쓰다: sonatype/nexus 컨테이너를 사용하여 이 동작을 재현할 수 있습니다. 따라서 이것은 GitLab의 문제가 아닙니다.
업데이트 2: 페이지 캐시 누락이 급증한 것으로 나타났습니다. 아마도이것이유는 무엇입니까, cgroups입니까? 그런데 기존 서버나 노트북은 왜 영향을 받지 않나요?
업데이트 3:mdraid1+lvm+btrfs를 사용하여 VM을 부팅할 때 재현할 수 있습니다! 추가 조사...
답변1
기억이 충격을 받는 것 같습니다. 컨테이너에 메모리가 부족하여 스왑 공간을 사용해야 합니다. 스왑 공간에 쓰면 메모리 스왑이 커널의 기능이고 디스크로 스왑되기 때문에 커널 및 디스크 활동이 높아집니다.