Nginx 기반의 Pod 내에서 S3 와 Mount 하기 위해 goofys 를 사용했던 적이 있습니다.
(goofys 말고 EBS 나 EFS 도 위시리스트에 있었지만, goofys 가 가장 적합하다고 판단하여 goofys 를 사용하게 되었습니다)
그림으로 표현하자면 아래와 같죠.
Nginx 가 provisioning 될 때 ConfigMap 으로 init.sh 를 주어 goofys 를 마운트 한 후 실행되도록 했습니다.
이런식으로 말이죠.
#!/usr/bin/env sh
set -eu
wget https://github.com/kahing/goofys/releases/latest/download/goofys
chmod +x goofys
/goofys <S3 Bucket> /var/nginx
...
nginx -g 'daemon off;'
생각대로 되면 좋을텐데.. 인생이 쉽지 않죠...
바로 에러가 발생해줍니다 🤦♂️
/goofys <S3 Bucket> /var/nginx
#2023/01/26 02:48:32.872554 main.FATAL Unable to mount file system, see syslog for details
자세한 에러 로그를 보고싶다면 syslog 를 참고하라고 하네요.
cat /var/log/syslog
어.. 근데 아무 내용이 없어요.. 경로가 저기가 아닌가 싶어 GitHub goofys 의 Issues 를 찾아봤습니다.
제대로 했는데 안보입니다. 아무래도 버그인거 같아요.
지금 당장 내가 할 수 있는 건 없을 거 같다는 생각을 하려던 찰나 좋은 수가 떠올랐어요 👀
goofys 를 background 로 실행시키는 것이 아니고 foreground 로 실행시켜 바로 로그가 찍히게 하는 것이죠.
-f 옵션을 주기만 하면 됩니다.
아래와 같은 에러를 출력합니다.
/goofys <S3 Bucket> /var/nginx
2023/01/26 02:48:49.217423 s3.INFO Switching from region 'us-east-1' to 'ap-northeast-2'
2023/01/26 02:48:49.256088 main.FATAL Mounting file system: Mount: mount: running fusermount: exit status 1
stderr:
fusermount: fuse device not found, try 'modprobe fuse' first
fuse mount 와 관련된 에러가 보입니다. fuse mount 은 goofys 에서도 안내하고 있습니다.
어렵지 않게 설치할 수 있습니다.
#!/usr/bin/env sh
set -eu
apk upgrade && apk update
apk add --no-cache fuse # fuse 추가
wget https://github.com/kahing/goofys/releases/latest/download/goofys
chmod +x goofys
/goofys <S3 Bucket> /var/nginx
...
nginx -g 'daemon off;'
이후 다시 실행 했는 데 동일한 에러가 계속 발생했습니다. 다행히 저랑 같은 문제를 겪는 Issues 가 있었습니다.
아하! 왜 안됐는지 알거 같습니다.
배포하려는 Nginx 기반의 Pod 는 Root 가 아닌 계정으로 실행됩니다. 따라서 fuse mount 할 권한이 없었던거죠!
따라서 Linux Capability 옵션으로 CAP_SYS_ADMIN 을 부여합니다.
그리고 Pod 를 재시작해보죠.
2023/01/26 03:02:57.725131 s3.INFO Switching from region 'us-east-1' to 'ap-northeast-2'
2023/01/26 03:02:57.761046 main.ERROR Unable to access '<s3 bucket>': permission denied
2023/01/26 03:02:57.761074 main.FATAL Mounting file system: Mount: initialization failed
여전히 안되긴 하지만, 아까와 로그 내용이 다릅니다. fuse mount 부분은 해결이 된 거 같아요 😀
그럼 로그 내용을 읽어볼까요?
S3 Bucket 에 접근할 권한이 없다는 군요.
하지만 분명 Pod 를 실행하기전 AWS IRSA 를 이용하여 해당 버킷에 접근할 수 있는 권한을 주었습니다.
환경변수로 잘 등록 되어있고, 실제로 aws s3 ls 명령어를 주었을 때 접근이 잘됩니다.
무엇이 문제일까요..??
혹시나 goofys 마운트 할 때 사용되는 AWS IAM Policy 권한이 부족한 거 같아 한번 찾아봤습니다.
Issues 에 이렇게 나와있네요.
읽어보니 s3:GetObject, s3:ListBucket 만 있어도 충분한 것 같습니다. 그리고 현재 사용하고 있는 IRSA 는 이미 권한을 다 갖고 있습니다.
그러면 다른 문제인 거 같습니다 🤨
뭘까요..?
사실 이 문제에 대해선 썩 명쾌하게 해결하진 못했습니다.
goofys 의 Usage 를 보면 AWS 에 접근하기 위해선 AWS_ACCESS_KEY_ID 와 AWS_SECRET_ACCESS_KEY 를 지정해줘야 합니다.
하지만 이미 Pod 는 IRSA 방식으로 자격 증명을 하기 때문에 AWS_ACCESS_KEY_ID 와 AWS_SECRET_ACCESS_KEY 는 사용하지 않습니다.
그래서 다시 한번 서칭해본 결과 같은 문제를 겪는 사람이 있었습니다. (Issues)
저랑 똑같이 AWS_WEB_IDENTITY_TOKEN_FILE 을 쓰고 싶어하네요. 해결 방법은 go sdk 를 1.23.13 버전 보다 높은 버전을 쓰라 합니다.
하지만 이미 1.44 버전을 사용하고 있습니다.. 이 문제는 아닌거 같아요..
이후 계속 삽질이 계속 되었지만, 명쾌하게 해결할 방법이 없었습니다.
결국 Secret 을 이용해서 Pod 에 AWS_ACCESS_KEY_ID 와 AWS_SECRET_ACCESS_KEY 건네주었습니다. (참고)
AWS IRSA 를 사용해서 자격 증명을 이미 했지만 goofys 를 사용하기 위해 AWS Cred 관련 데이터를 환경변수로 또 건네준 것이 마음에 들진 않습니다..
하지만 지금 당장은 명쾌한 답이 없어서 이 방식을 통해 goofys 를 마운트하였습니다 🤨
goofys 자체가 2020년 4월 5일 이후론 release 가 없어서 goofys 를 사용하는 이상 명쾌한 답을 얻긴 어려워보입니다 😢
aws cli 에서 제공해주는 aws s3 sync 를 이용해서 비슷한 기능을 제공해줄 순 있지만.. 이보단 goofys 가 더 편리할 거 같아 goofys 로 갑니다..
아무튼 이번 에러도 무사히 해결했다 👍
'트러블 빵야' 카테고리의 다른 글
[Github Action] 타노스는 이런 느낌일까? RUNNER_TOKEN must be set (7) | 2023.02.20 |
---|---|
[Kubernetes] aws_auth 를 찾을 수 없습니다.. (0) | 2022.12.23 |