괴로워, nginx worker 프로 세 스 메모리 가 계속 상승 합 니 다!

배경
앞의 두 글 은 클 라 우 드 호스트 lua openresty 프로젝트 의 용기 화 과정 을 이야기 했다. 테스트 환경 에서 한 동안 의 검증 을 거 쳐 모든 것 이 비교적 순 조 롭 고 온라인 에서 그 레이스 케 일 을 시작 했다.
하지만 호황 은 길지 않다.그 레이스 케 일이 얼마 지나 지 않 아 사용 top pod 으로 보 았 을 때 메모리 가 가득 차 있 는 것 을 발 견 했 습 니 다. 처음에 k8s resources limit memory(2024Mi) 의 분배 가 작 아 졌 다 고 의심 하기 시 작 했 습 니 다. 확대 후 (4096 Mi) pod 를 다시 시작 하면 얼마 지나 지 않 아 다시 꽉 찼 습 니 다.
이 어 방 류 량 이 많 고 부하 가 높 아서 생 긴 것 으로 의심 되 며 확대 hpa 하고 재 개 했다.
여기까지 pod 내부 프로그램 에 눈 을 돌 렸 다. 또 어디 에 메모리 누 출 이 있 었 는 지 짐작 했다.
어디
  • 시간 이 지나 면 메모리 가 오르락내리락 하고 nginx worker (하위 프로 세 스) id 번호 가 계속 증가 합 니 다. 누가 프로 세 스 를 죽 였 습 니까?
  • 클 라 우 드 호스트 에 이런 문제 가 발생 하지 않 았 는데 k8s 가 일 으 킨 것 일 까?
  • podresources limit memory 증가 와 hpa 증 가 는 모두 해결 되 지 않 았 다.
  • nginx -s reload 메모 리 를 풀 수 있 었 지만 얼마 지나 지 않 아 꽉 찼 다.

  • 해결 방법
    누가 죽 였 습 니까?
    명령: ps aux
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root         1  0.0  0.0 252672  5844 ?        Ss   Jun11   0:00 nginx: master process /data/openresty/bin/openresty -g daemon off;
    nobody     865 10.1  0.3 864328 590744 ?       S    14:56   7:14 nginx: worker process
    nobody     866 13.0  0.3 860164 586748 ?       S    15:13   7:02 nginx: worker process
    nobody     931 15.6  0.2 759944 486408 ?       R    15:31   5:37 nginx: worker process
    nobody     938 13.3  0.1 507784 234384 ?       R    15:49   2:23 nginx: worker process

    woker 프로 세 스 번호 가 1000 에 가 까 워 진 것 을 발견 하면 끊임없이 kill 에 의 해 바 뀌 었 을 것 입 니 다. 그것 은 도대체 누가 한 짓 입 니까?dmesg 명령 통과:
    [36812300.604948] dljgo invoked oom-killer: gfp_mask=0xd0, order=0, oom_score_adj=999
    [36812300.648057] Task in /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pode4ad18fa_3b8f_4600_a557_a2bc853e80d9.slice/docker-c888fefbafc14b39e42db5ad204b2e5fa7cbfdf20cbd621ecf15fdebcb692a61.scope killed as a result of limit of /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pode4ad18fa_3b8f_4600_a557_a2bc853e80d9.slice/docker-c888fefbafc14b39e42db5ad204b2e5fa7cbfdf20cbd621ecf15fdebcb692a61.scope
    [36812300.655582] memory: usage 500000kB, limit 500000kB, failcnt 132
    [36812300.657244] memory+swap: usage 500000kB, limit 500000kB, failcnt 0
    [36812300.658931] kmem: usage 0kB, limit 9007199254740988kB, failcnt 0
    ……
    [36675871.040485] Memory cgroup out of memory: Kill process 16492 (openresty) score 1286 or sacrifice child

    cgroup 메모리 가 부족 한 것 을 발견 하면 리 눅 스 커 널 은 일부 메모 리 를 회수 하고 시스템 을 계속 실행 할 수 있 도록 프로 세 스 kill 을 선택 합 니 다.
    kill 이 nginx worker 프로 세 스 를 떨 어 뜨 린 후 메모 리 를 방출 하여 문 제 를 일시 적 으로 해결 하 였 으 나 근본 적 인 문 제 는 아직 해결 되 지 않 았 습 니 다.
    왜 클 라 우 드 호스트 에 문제 가 없 습 니까?
    클 라 우 드 호스트 의 lua 코드 를 로 컬 로 복사 하여 비교 한 결과 코드 자체 에 문제 가 없 음 을 발견 하 였 습 니 다.
    그것 은 다른 방면 의 문제 가 일 으 킬 수 밖 에 없다.
    어쩌면 좋아?
    상기 두 가지 점 모두 포 지 셔 닝 문 제 를 잘 파악 하지 못 했 기 때문에 top, pmap, gdb 등 명령 을 통 해 문 제 를 조사 할 수 밖 에 없 을 것 같다.
    1. top 메모리 유출 프로 세 스top 을 통 해 어떤 프로 세 스 가 메모리 사용량 이 높 은 지 확인 합 니 다.
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                                                               
      942 nobody    20   0  618.9m 351.7m   4.2m S  18.0  0.2   4:05.72 openresty                                                                                                                                                             
      943 nobody    20   0  413.8m 146.7m   4.2m S  11.7  0.1   1:18.93 openresty                                                                                                                                                             
      940 nobody    20   0  792.0m 524.9m   4.2m S   7.0  0.3   6:25.81 openresty                                                                                                                                                             
      938 nobody    20   0  847.4m 580.2m   4.2m S   3.7  0.3   7:15.97 openresty 
        1 root      20   0  246.8m   5.7m   3.9m S   0.0  0.0   0:00.24 openresty                                                                                                                                               

    2. pmap 프로 세 스 의 메모리 할당 보기pmap -x pid 을 통 해 이 프로 세 스 의 메모리 분 배 를 찾 아 낸 결과 0000000000af7000 큰 메모리 분배 가 존재 하 는 것 을 발견 했다.
    Address           Kbytes     RSS   Dirty Mode  Mapping
    0000000000400000    1572     912       0 r-x-- nginx
    0000000000788000       4       4       4 r---- nginx
    0000000000789000     148     128     116 rw--- nginx
    00000000007ae000     140      28      28 rw---   [ anon ]
    0000000000a15000     904     900     900 rw---   [ anon ]
    0000000000af7000  531080  530980  530980 rw---   [ anon ]
    0000000040048000     128     124     124 rw---   [ anon ]
    ……

    3. / proc / pid / smaps 포 지 셔 닝 메모리 유출 주소 범위
    큰 메모리 의 메모리 주 소 를 가 져 온 후 cat /proc/pid/smaps 명령 을 통 해 메모리 세그먼트 의 구체 적 인 시작 위 치 를 봅 니 다.
    00af7000-21412000 rw-p 00000000 00:00 0                                  [heap]
    Size:             533612 kB
    Rss:              533596 kB
    Pss:              533596 kB
    Shared_Clean:          0 kB
    Shared_Dirty:          0 kB
    Private_Clean:         0 kB
    Private_Dirty:    533596 kB
    Referenced:       533596 kB
    Anonymous:        533596 kB
    AnonHugePages:         0 kB
    Swap:                  0 kB
    KernelPageSize:        4 kB
    MMUPageSize:           4 kB
    Locked:                0 kB
    VmFlags: rd wr mr mw me ac sd

    4. gcore 저장 프로 세 스 이미지 및 메모리 컨 텍스트
    gcore pid

    "core. pid" 파일 을 가 져 옵 니 다.
    5. gdb 메모리 정보 불 러 오기
    gdb core.pid
    
    sh-4.2$ gdb core.942
    GNU gdb (GDB) Red Hat Enterprise Linux 7.*
    Copyright (C) 2013 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later 
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-redhat-linux-gnu".
    For bug reporting instructions, please see:
    ...
    [New LWP pid]
    Core was generated by `nginx: worker process'.
    #0  0x00007ff9435e1463 in ?? ()
    "/tmp/core.942" is a core file.
    Please specify an executable to debug.
    (gdb) 

    이상 명령 창 에 들 어가 기
    6. dump binary 메모리 유출 내용 내 보 내기
    3 시 에 메모리 시작 주 소 를 받 았 습 니 다. 이 때 메모리 주 소 를 내 보 냅 니 다.
    dump binary memory worker-pid.bin 0x00af7000 0x21412000

    내 보 낼 파일 크기 보기
    sh-4.2$ du -sh worker-pid.bin
    511M    worker-pid.bin

    7. 바 이 너 리 파일 분석hex 도구 로 바 이 너 리 파일 을 열 면 대량의 json 대상 을 발견 할 수 있 습 니 다. json 대상 을 분석 한 결과 pod 의 so 암호 화 라 이브 러 리 는 오래된 (git 에 서 는 새로운 것 이 아 닙 니 다) 이 고 클 라 우 드 호스트 는 새로운 것 에 의존 합 니 다.
    so 라 이브 러 리 를 교체 하고 pod 를 다시 시작 합 니 다. 문제 해결! ~
    총결산
    생산 환경 에서 의 메모리 누 출 은 비교적 골 치 아 픈 문제 이 므 로 상기 방식 으로 분석 하 는 것 도 좋 은 사고 이다.

    좋은 웹페이지 즐겨찾기