업그레이드 후 Redis 오류 발생

안녕하세요,

웹 프론트엔드를 통해 업그레이드한 후 더 이상 내 사이트에 접속할 수 없습니다. 아무것도 변경하지 않았고, 그냥 업그레이드 버튼만 클릭했을 뿐입니다! 에러 메시지는 Redis 연결 문제와 관련이 있는 것 같습니다. 많이 검색해 보았지만 아직 도움이 될 만한 정보를 찾지 못했습니다. production.log는 비어 있습니다. Digital Ocean에서 Ubuntu를 사용 중입니다. 18개월 동안 문제없이 잘 작동해 왔으며, 6개월 전 디스크 공간이 부족했을 때 용량을 성공적으로 증설한 것 외에는 에러가 없었습니다.

디스크 공간은 정상입니다: :-

Filesystem      Size  Used Avail Use% Mounted on
overlay          49G   25G   24G  52% /
tmpfs            64M     0   64M   0% /dev
tmpfs          1001M     0 1001M   0% /sys/fs/cgroup
shm             512M  8.0K  512M   1% /dev/shm
/dev/vda1        49G   25G   24G  52% /shared
tmpfs          1001M     0 1001M   0% /proc/acpi
tmpfs          1001M     0 1001M   0% /proc/scsi
tmpfs          1001M     0 1001M   0% /sys/firmware

unicorn.stdout.log에는 다음이 표시됩니다

> 2020-06-03T06:29:28.352Z pid=715 tid=osk2fuo0n ERROR: Error fetching job: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL)
> 2020-06-03T06:29:28.353Z pid=715 tid=osk2fszrb ERROR: Error fetching job: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL)
> 2020-06-03T06:29:28.354Z pid=715 tid=osk2fsjw3 ERROR: Error fetching job: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL)
> 2020-06-03T06:29:28.354Z pid=715 tid=osk2ftlhz ERROR: Error fetching job: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL)
> 2020-06-03T06:29:28.355Z pid=715 tid=osk2ftr43 ERROR: Error fetching job: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL)
> Starting up 1 supervised sidekiqs
> Loading Sidekiq in process id 725

처음에는 수동으로 앱을 재구축해 보았습니다.

그 후 apt upgrade docker를 실행하고 reboot 명령으로 서버를 재부팅했으며, ./launcher rebuild app을 사용하여 재구축했습니다.

redis-cli ping 명령에는 PONG 응답이 돌아옵니다.

ss -t
State      Recv-Q Send-Q Local Address:Port                 Peer Address:Port   
ESTAB      0      0      104.248.166.162:ssh                  5.81.114.19:56270 
ESTAB      0      0      104.248.166.162:ssh                  5.81.114.19:56211 

ps -axf 명령으로 확인한 결과 프로세스가 실행 중입니다.

  PID TTY      STAT   TIME COMMAND
 2378 pts/1    Ss     0:00 /bin/bash --login
 2849 pts/1    R+     0:00  \_ ps -axf
    1 pts/0    Ss+    0:00 /bin/bash /sbin/boot
  627 pts/0    S+     0:00 /usr/bin/runsvdir -P /etc/service
  628 ?        Ss     0:00  \_ runsv rsyslog
  641 ?        Sl     0:00  |   \_ rsyslogd -n
  629 ?        Ss     0:00  \_ runsv cron
  640 ?        S      0:00  |   \_ cron -f
  630 ?        Ss     0:00  \_ runsv unicorn
  639 ?        S      0:00  |   \_ /bin/bash config/unicorn_launcher -E producti
  665 ?        Sl     0:09  |       \_ unicorn master -E production -c config/un
  725 ?        SNl    0:12  |       |   \_ sidekiq 6.0.7 discourse [0 of 5 busy]
  750 ?        Sl     0:20  |       |   \_ unicorn worker[0] -E production -c co
  758 ?        Sl     0:17  |       |   \_ unicorn worker[1] -E production -c co
 2848 ?        S      0:00  |       \_ sleep 1
  631 ?        Ss     0:00  \_ runsv postgres
  635 ?        S      0:00  |   \_ svlogd /var/log/postgres
  636 ?        S      0:00  |   \_ /usr/lib/postgresql/12/bin/postmaster -D /etc
  659 ?        Ss     0:00  |       \_ postgres: 12/main: checkpointer
  660 ?        Ss     0:00  |       \_ postgres: 12/main: background writer
  661 ?        Ss     0:00  |       \_ postgres: 12/main: walwriter
  662 ?        Ss     0:00  |       \_ postgres: 12/main: autovacuum launcher
  663 ?        Ss     0:00  |       \_ postgres: 12/main: stats collector
  664 ?        Ss     0:00  |       \_ postgres: 12/main: logical replication la
  691 ?        Ss     0:00  |       \_ postgres: 12/main: discourse discourse [l
 1848 ?        Ss     0:00  |       \_ postgres: 12/main: discourse discourse [l
 2633 ?        Ss     0:00  |       \_ postgres: 12/main: discourse discourse [l
 2675 ?        Ss     0:00  |       \_ postgres: 12/main: discourse discourse [l
 2840 ?        Ss     0:00  |       \_ postgres: 12/main: discourse discourse [l
  632 ?        Ss     0:00  \_ runsv nginx
  634 ?        S      0:00  |   \_ nginx: master process /usr/sbin/nginx
  654 ?        S      0:02  |       \_ nginx: worker process
  655 ?        S      0:00  |       \_ nginx: cache manager process
  633 ?        Ss     0:00  \_ runsv redis
  637 ?        S      0:00      \_ svlogd /var/log/redis
  638 ?        Sl     0:05      \_ /usr/bin/redis-server *:6379

어떤 아이디어라도 있을까요? 저는 전문가가 아니라서 다시 실행되도록 하는 방법을 찾는 데 큰 어려움을 겪고 있습니다. 놓치고 있는 단순한 부분이 있을까요? 문제를 찾는데 도움이 될 수 있는 다른 확인 방법이 있을까요?

감사합니다.

아… 재부팅을 하고 당연히 해야 할 일들을 다 했군요…

컨테이너 설정(비밀번호 제외)을 붙여넣어 주실 수 있나요? redis 템플릿이 섞여 있나요?

docker logs app에서 주목할 만한 내용이 있나요?

컨테이너 내부에서 localhost가 제대로 해석(resolving)되고 있나요?

샘, 안녕하세요. 제 지식이 부족해서 죄송합니다.

app.yml 파일을 말씀하시는 건가요?

도커 로그(docker logs)가 어떤 로그를 가리키는지 모르겠습니다. 저는 ./launcher logs app 명령어를 실행해 보았는데요.

run-parts: executing /etc/runit/1.d/00-ensure-links
run-parts: executing /etc/runit/1.d/00-fix-var-logs
run-parts: executing /etc/runit/1.d/anacron
run-parts: executing /etc/runit/1.d/cleanup-pids
Cleaning stale PID files
run-parts: executing /etc/runit/1.d/copy-env
run-parts: executing /etc/runit/1.d/letsencrypt
[Wed 03 Jun 2020 06:34:47 AM UTC] Domains not changed.
[Wed 03 Jun 2020 06:34:47 AM UTC] Skip, Next renewal time is: Wed Jul  1 00:35:12 UTC 2020
[Wed 03 Jun 2020 06:34:47 AM UTC] Add '--force' to force to renew.
[Wed 03 Jun 2020 06:34:47 AM UTC] Installing key to:/shared/ssl/forum.tritalk.co.uk.key
[Wed 03 Jun 2020 06:34:47 AM UTC] Installing full chain to:/shared/ssl/forum.tritalk.co.uk.cer
[Wed 03 Jun 2020 06:34:47 AM UTC] Run reload cmd: sv reload nginx
warning: nginx: unable to open supervise/ok: file does not exist
[Wed 03 Jun 2020 06:34:47 AM UTC] Reload error for :
[Wed 03 Jun 2020 06:34:48 AM UTC] Domains not changed.
[Wed 03 Jun 2020 06:34:48 AM UTC] Skip, Next renewal time is: Thu Jul  9 00:35:12 UTC 2020
[Wed 03 Jun 2020 06:34:48 AM UTC] Add '--force' to force to renew.
[Wed 03 Jun 2020 06:34:48 AM UTC] Installing key to:/shared/ssl/forum.tritalk.co.uk_ecc.key
[Wed 03 Jun 2020 06:34:48 AM UTC] Installing full chain to:/shared/ssl/forum.tritalk.co.uk_ecc.cer
[Wed 03 Jun 2020 06:34:48 AM UTC] Run reload cmd: sv reload nginx
warning: nginx: unable to open supervise/ok: file does not exist
[Wed 03 Jun 2020 06:34:48 AM UTC] Reload error for :
Started runsvdir, PID is 627
ok: run: redis: (pid 638) 0s
ok: run: postgres: (pid 636) 0s
chgrp: invalid group: ‘syslog’
rsyslogd: imklog: cannot open kernel log (/proc/kmsg): Operation not permitted.
rsyslogd: activation of module imklog failed [v8.1901.0 try https://www.rsyslog.com/e/2145 ]
supervisor pid: 639 unicorn pid: 665

컨테이너 안에서 명령어를 시도해 보았는데, 이것이 말씀하신 내용인지 잘 모르겠습니다.

tritalk@TriTalk-Discourse:/var/discourse$ sudo ./launcher enter app
root@TriTalk-Discourse-app:/var/www/discourse# curl http://localhost:8080
curl: (7) Failed to connect to localhost port 8080: Connection refused

네, app.yml 파일입니다. 하지만 비밀번호나 민감한 정보는 반드시 제거해 주세요.

## 이것은 올인원, 독립형 Discourse Docker 컨테이너 템플릿입니다
##
## 이 파일에 변경 사항을 적용한 후에는 반드시 다시 빌드해야 합니다.
## /var/discourse/launcher rebuild app
##
## 편집할 때 *매우* 주의하세요!
## YAML 파일은 공백이나 정렬 오류에 대해 매우 민감합니다!
## 필요할 경우 http://www.yamllint.com/ 에서 이 파일을 검증하세요.

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Lets Encrypt(https)를 추가하려면 아래 두 줄의 주석을 해제하세요.
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## 이 컨테이너는 어떤 TCP/IP 포트를 노출해야 합니까?
## Discourse를 Apache나 nginx와 같은 다른 웹서버와 포트 공유를 원한다면,
## 자세한 내용은 https://meta.discourse.org/t/17247 를 참조하세요.
expose:
  - "80:80"   # http
  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## db_shared_buffers는 총 메모리의 최대 25%로 설정하세요.
  ## 감지된 RAM에 따라 bootstrap이 자동으로 설정하거나, 직접 오버라이드할 수 있습니다.
  db_shared_buffers: "128MB"

  ## 정렬 성능을 향상시킬 수 있지만, 연결당 메모리 사용량이 증가합니다.
  #db_work_mem: "40MB"

  ## 이 컨테이너는 어떤 Git 리비전을 사용해야 합니까? (기본값: tests-passed)
  #version: tests-passed

env:
  LANG: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## 동시 웹 요청은 얼마나 지원됩니까? 메모리와 CPU 코어 수에 따라 다릅니다.
  ## 감지된 CPU에 따라 bootstrap이 자동으로 설정하거나, 직접 오버라이드할 수 있습니다.
  UNICORN_WORKERS: 2

  ## TODO: 이 Discourse 인스턴스가 응답할 도메인 이름
  ## 필수입니다. Discourse는 IP 주소만으로는 작동하지 않습니다.
  DISCOURSE_HOSTNAME: forum.xxxx.co.uk

  ## 컨테이너가 위에서 지정된 호스트 이름(-h 옵션)과 동일한 이름으로 시작되도록 하려면 주석을 해제하세요.
  ## (기본값 "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: 초기 가입 시 관리자 및 개발자로 지정될 쉼표로 구분된 이메일 목록
  ## 예: 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'admin@xxxx.co.uk'

  ## TODO: 새 계정을 검증하고 알림을 보내는 데 사용되는 SMTP 메일 서버
  # SMTP 주소, 사용자 이름, 비밀번호는 필수입니다.
  # 경고: SMTP 비밀번호의 '#' 문자는 문제를 일으킬 수 있습니다!
  DISCOURSE_SMTP_ADDRESS: in-v3.mailjet.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: xxxx
  DISCOURSE_SMTP_PASSWORD: "xxxx"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (선택 사항, 기본값 true)

  ## Lets Encrypt 템플릿을 추가했다면, 무료 SSL 인증서를 받으려면 아래 주석을 해제하세요.
  LETSENCRYPT_ACCOUNT_EMAIL: admin@xxxx.co.uk

  ## 이 Discourse 인스턴스의 CDN 주소 (pull로 설정됨)
  ## 자세한 내용은 https://meta.discourse.org/t/14857 를 참조하세요.
  #DISCOURSE_CDN_URL: //discourse-cdn.example.com

## Docker 컨테이너는 상태가 없으며, 모든 데이터는 /shared에 저장됩니다.
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## 플러그인은 여기에 추가합니다.
## 자세한 내용은 https://meta.discourse.org/t/19157 를 참조하세요.
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - mkdir -p plugins
          - git clone https://github.com/discourse/discourse-adplugin.git
          - git clone https://github.com/discourse/discourse-affiliate.git

## 빌드 후 실행할 모든 사용자 정의 명령
run:
  - exec: echo "Beginning of custom commands"
  ## 첫 번째 가입 시 'From' 이메일 주소를 설정하려면 주석을 해제하고 변경하세요:
  ## 첫 가입 이메일을 받은 후, 해당 줄을 다시 주석 처리하세요. 한 번만 실행하면 됩니다.
  - exec: rails r "SiteSetting.notification_email='admin@xxxx.co.uk'"
  - exec: echo "End of custom commands"

정말 난감한 상황이네요. 현재 어떤 버전의 Docker를 사용 중이신가요? docker info 명령어는 어떤 결과를 반환하나요?

틀린 말이 아닙니다! 데이터베이스를 찾을 수 없는 것처럼 보이네요. 사이트로 들어가면 제목만 있는 화면이 표시됩니다.

docker info :-

Client:
 Debug Mode: false

Server:
 Containers: 2
  Running: 1
  Paused: 0
  Stopped: 1
 Images: 6
 Server Version: 19.03.11
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
 init version: fec3683
 Security Options:
  apparmor
  seccomp
   Profile: default
 Kernel Version: 4.4.0-179-generic
 Operating System: Ubuntu 16.04.6 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 1
 Total Memory: 1.953GiB
 Name: TriTalk-Discourse
 ID: SYIS:XPWU:W2SP:NYNA:GFP7:DNVK:E7JF:553N:EGWF:OR7M:TV2E:A6ZX
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

WARNING: No swap limit support

안전 모드를 시도해 볼 수 있나요?

안전 모드를 사용했는데, 플러그인을 비활성화하지 않으면 실패합니다. 따라서 업그레이드 이후 어떤 플러그인이 문제를 일으키고 있는 것 같습니다. yml 파일에서 해당 플러그인을 주석 처리하고 앱을 다시 빌드하니 모두 정상 작동했습니다. 문제의 원인은 discourse-affiliate 또는 discourse-adplugin 중 하나입니다. 나중에 더 자세히 조사해 보겠지만, 일단 사이트는 다시 정상적으로 실행되고 있습니다. 도움을 주셔서 감사합니다. 앞으로 예비 점검을 할 때는 안전 모드를 사용해야겠다는 점을 스스로에게 기록해 둡니다!

플러그인 영역의 형식이 올바르게 설정되어 있지 않은 것 같습니다. 이것이 문제를 일으키는 원인일 수 있습니다.

실제로는 다음과 같이 되어야 합니다:

        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-adplugin.git
          - git clone https://github.com/discourse/discourse-affiliate.git

(-mkdir -p plugins를 제거)
이렇게 하면 플러그인 관련 문제가 해결될 것입니다.

Bhanu, 감사합니다. 시도해 보겠습니다. 오늘까지 잘 작동하고 있었으니 좀 이상하네요. 아마도 최신 Docker 릴리스에서 보안이 강화된 것 같습니다.

제가 틀렸을 수도 있습니다. 저는 yml 파일에서 해당 파라미터를 사용한 적이 없고, 지금까지는 잘 작동하고 있습니다.

@carlb 님, 안녕하세요.

참고로, Redis는 주로 백그라운드 작업(그리고 이를 지원하는 작업 스케줄러인 Sidekiq)에 사용됩니다. 그리고 참고로, 저는 개발 환경에서는 이러한 "백그라운드 작업"이 실행되지 않기를 원하기 때문에 Redis나 Sidekiq를 실행하지 않은 채로 Discourse를 실행하는 경우가 많습니다.

따라서 Redis가 실행되지 않더라도 Discourse 포럼은 여전히 핵심 포럼, 주제, 사용자, 게시물 등이 표시되어야 합니다. 제가 이 참고 사항을 언급하는 이유는, 질문 제목을 다음과 같이 지으셨기 때문입니다:

업그레이드 후 Redis 오류

… 그리고 Redis 자체와 직접적인 관련이 없는 기본적인 문제들이 많이 보이는 포럼의 스크린샷을 유용하게 제공해 주셨기 때문입니다.

설명해 주셔서 감사합니다. 이 모든 것들이 어떻게 연결되는지에 대해 잘 알고 있지 못해서, 항상 잘 작동하곤 해서 깊이 파고들 필요가 없었습니다. 그래서 앞으로 도움이 될 것 같습니다. 제가 발견한 오류들이 전부 Redis 연결 실패와 관련된 것들뿐이라, 이것이 근본 원인일 것 같다고 짐작했습니다. 평소에는 이런 기본적인 문제를 해결해 주던 일반적인 방법들도 하나도 작동하지 않았습니다.