728x90

엔지니어에게 로그는 물과 같습니다.
무슨 일이 일어나더라도 충분한 로그가 있으면 해결할 수 있기 때문입니다. 
다양한 환경에서 Proxy로 활용되는 엔진엑스에서도 마찬가지입니다.
문제는 로그가 너무 많은 경우 인스턴스 운용이 어려울 수 있다는 것이죠. 


원칙#1, 로그는 일단 끄고 시작하자

이게 무슨말이냐구요?
로그를 왜 끄고 시작하냐구요?
네, 로그를 끄고 시작하는 것을 권장합니다.

엔진엑스 구성 파일은 복잡합니다. 
여러개의 분리된 파일을 include 로 쓰는 것이 기본 구성이고
디폴트 구성 자체가 이렇게 되어 있다보니 
대부분 nginx.conf 에서 /conf.d/*.conf 로 이어지는 구성을
채택하고 사용하고 계실 겁니다.

권고 드리는 기본 구성은 nginx.conf 에서 access_log를 끄고
location 지시자 등 필요한 경우에 access_log를 활성화하는 방식입니다. 

// nginx.conf

http {
    ...
    log_format  main  '$remote_addr - $remote_user [$time_local] "$scheme" "$request" '
                      '$status $upstream_status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$http_host" "$upstream_addr"';

    access_log off;
    ...
    ...
    include /etc/nginx/conf.d/*.conf;
}

위 설정은 nginx 기본 설정 파일인 nginx.conf의 예입니다. 
http 서빙을 위해 http 블록이 들어가 있고 
로그 형식을 지정하는 log_format과 access_log 지시자가 있습니다. 

access_log 는 기본적으로 활성화 되어 있기 때문에
off 를 지정하여 http 요청에 대해 기본적으로 로깅을 하지 않도록 구성했습니다. 
패키지 저장소에서 nginx를 설치했기 때문에 /etc/nginx/에 필요한 파일들이 위치해 있고 
conf.d 경로 아래의 conf 확장자를 가진 파일들을 include 하고 있습니다.

 

원칙#2, 로그는 필요한 경우에만 켜자

로깅을 껐으면 이제는 필요한 부분에서 로깅을 켜야 합니다. 
보통은 location 블록을 활용해 업스트림 서버를 구분하거나 
필요한 프록시 기능을 구현하고 계실겁니다. 
다음의 설정은 location 블록 내에서 로깅을 활성화하는 예시입니다. 

// /conf.d/default.conf

server {
    ...
    location = /no-log-path {
        ...
        ## 여러 설정들 ##
        ...
    }

    location = /admin {
        ...
        access_log /var/log/nginx/admin.access.log  main;
        ...
    }
}

이렇게 구성하면 /no-log-path 경로로 들어오는 요청들은
앞서 http 블록에서 지정한 access_log off 에 따라 로깅을 하지 않습니다. 
대신 중요한 경로인 /admin 으로 들어오는 요청들은 
앞서 지정한 main 로그 형식에 따라 지정된 경로에 로그를 남기게 됩니다. 

 

원칙#3, 필요한 경우 샘플링해서 로그를 남기자

이렇게 필요한 경우에만 로그를 남기도록 구성했더라도 
요청량이 너무 많은 경우에는 제한적으로 로그를 남길 필요가 있습니다. 
엔진엑스의 access_log 지시자는 if 구문을 이용해 조건부로 활성화 할 수 있습니다.
위의 예제를 조금 수정해 보겠습니다. 

// /conf.d/default.conf

split_clients $remote_addr $is_need_to_logged {
    5%    1;
    *     0;
}

server {
    ...
    location = /no-log-path {
        ...
        ## 여러 설정들 ##
        ...
    }

    location = /admin {
        ...
        access_log /var/log/nginx/admin.access.log  main if=$is_need_to_logged;
        ...
    }
}

split_clients 지시자를 이용해 사용자 IP중 5%에 대해서
$is_need_to_logged 라는 변수 값을 1로 지정하도록 했습니다. 
1은 true의 의미를 갖는다는 것을 활용해 access_log 지시자의 if 구문에 활용했습니다. 
이렇게 구성한 설정의 흐름을 정리하면 다음과 같습니다.

  1. 엔진엑스 서버로 http 요청이 들어오면 일단 로그를 비활성화 한다
  2. /admin 경로로 들어오는 요청은 main 형식으로 /var/log/nginx/admin.access.log 파일에 로그를 기록한다
  3. 다만, 요청 사용자 IP기준으로 5%의 사용자에 대해서만 로그를 남긴다

로그는 중요합니다. 
하지만 로그는 가장 큰 부담중 하나입니다.
적절한 규모로 로그를 관리하는 것이
편안한 취침의 지름길입니다.

엔진엑스의 다양한 활용에 대해 알고싶다면
제가 번역한 <엔진엑스 쿡북>을 읽어보시는 건 어떨까요? :-)

 

 

NGINX 쿡북 - 예스24

애플리케이션의 성능, 신뢰성, 보안을 책임지는만능 웹 서버 소프트웨어 엔진엑스 제대로 활용하기엔진엑스 설치 및 사용법부터 다양한 모듈과 실전 운영 팁까지 다룬다. 엔진엑스라는 애플리

www.yes24.com

 

 

본 포스팅은 제휴 마케팅을 통해
소정의 수수료를 지급받는 링크를 포함하고 있습니다

728x90
728x90

오랜만에 소식 전합니다.
요즘 가장 뜨거운 분야중 하나인 관찰가능성!
영어로 옵저버빌리리~ Observability라고 하죠.
K8s처럼 더 멋진 용어로는 o11y라고도 합니다. 

<관찰 가능성 엔지니어링>은 packt에서 출간된
<Cloud-native Observability with OpenTelemetry>의 번역서입니다.
관찰 가능성을 공부하시는 분이라면
오픈텔레메트리 OpenTelemetry라는 이름을
한번쯤 들어보셨을거라 생각합니다!

 

관찰 가능성을 위한 도구는 무척 많습니다. 
하지만 너무 많은 도구들이 난립해있죠.
초보자들에게는 어디서부터 어떻게 시작해야 하는지
시작 자체가 어려워지는 상황으로 치닫고 있기도 합니다.

이 책은 오픈텔레메트리를 중심으로 
그라파나, 예거, 집킨 등 다양한 도구를 사용하여
여러분의 소프트웨어와 인프라에 대한 관찰 가능성 체계 구성을 가이드 해줍니다.

왜 OS 영역인지는 잘...

원서에서 사용한 버전이 조금 예전 버전이라
한 땀, 한 땀, 새로운 버전에 맞추어 소스코드를 개정했고
쉽게 실습하실 수 있도록 정리했습니다.

원저자의 깃허브보다는
책의 내용을 하나씩 따라 입력하면서
소스코드를 시험하는 것을 추천드립니다!
자세한 내용은 각 서점에서 확인해 보시기 바랍니다!

 

관찰 가능성 엔지니어링 - 예스24

“또 오류가 발생했다.. 정확한 원인이 뭐지?” “잠재적인 오류도 미리 알 수 있을까?”이 질문들의 답은 관찰 가능성에 있다! *OpenTelemetry 설치 및 사용법 수록마이크로서비스와 클라우드가 보

www.yes24.com

 

본 포스팅은 제휴마케팅을 통해 소정의 수수료를 지급 받을 수 있습니다.
번역서는 번역비로 끝인지라 링크를 통해 책을 구입하시면
다음 번역서를 위해 다시 달릴 수 있는 원동력이 될거라 믿습니다!

 

728x90
728x90

.env 파일을 이용해 환경 변수를 설정하는 방식이 널리 사용되고 있습니다.
개인적으로는 dotenv 패키지를 이용해서 .env 파일을 사용중인데요
오랜만에 프로젝트 환경을 구성 하다보니 dotenv 패키지가 없더군요.

그런데!

pip install dotenv를 아무리 해도 설치되지 않는 당혹스러움을 마딱드렸습니다. 
패키지가 없어진건가? 사내 네트워크에서 막힌건가? 온갖 생각을 하다 찾아보니...
dotenv의 패키지 이름은 python-dotenv 였습니다 ㅠㅠ 
오랜만에 만난 그 이름... 어쩐지 익숙합니다.

pip install python-dotenv

당황하지 말고, python-dotenv를 설치하십시오, 닝겐!

728x90
728x90

CentOS를 비롯한 Redhat 계열에서는 Yum을 이용해 패키지를 관리합니다.
간혹 yum 으로 패키지를 설치하다 패키지 데이터베이스를 열 수 없다는 에러를 만날 수 있습니다.
영문 기준으로 rpmdb open failed 라는 메세지가 바로 그것이죠.

이런 상황을 해결하는 가장 쉬운 방법은 RPM DB 삭제입니다.
DB를 삭제한다고 뭔가 큰 일이 일어나는 것은 아닙니다. 
DB 자체에 뭔가 이슈가 생긴 경우이기 때문에 
DB 파일 삭제후 다시 생성하면 됩니다. 

rm -f /var/lib/rpm/_db*
rpm -vv --rebuilddb
728x90
728x90

리모트에 새로 생성된 브랜치가 있다면 가져오도록 하기 위해 다음의 명령을 사용합니다.
이 명령을 이용해 새로 생성된 브랜치의 정보를 로컬에 기록해 둘 수 있습니다.
네, 기록만 하는 것이고 소스코드를 실제로 가져오는 것은 아닙니다.

git remote update

 

그런데 이렇게 기록해둔 브랜치 정보는
특정 브랜치의 폐기와 같이 변화된 내용을 자동으로 반영하지는 못합니다. 
물론, `git branch -D` 옵션으로 로컬에서 정보를 지울 수 있지만
브랜치가 많은 경우에는 좋은 선택지가 아닙니다.

이럴 때는 다음의 명령을 이용해 특정 원격지의 브랜치를 확인하고
삭제된 브랜치는 로컬 브랜치 기록에서도 삭제하도록 할 수 있습니다.

git fetch {리모트명} --prune

혹은

git remote prune {리모트명}

참 쉽죠?

728x90
728x90

매일 매일 하지 않으면 다 까먹는게 k8s인 것 같습니다. 
여느 오픈소스들과 마찬가지로 마이너버전 업데이트가 이루어지더라도
여러가지 변경되는 점들이 워낙 많기 때문일 것 같습니다.

그 중에서도! 
ServiceAccount를 생성했을 때 같이 생성되던 Token이 만들어지지 않는 것은
분명 꼼꼼히 이것저것 살피지 않았다면 빠지기 쉬운 함정인 것 같습니다 ㅠㅠ

한 줄 요약 : k8s 1.24 버전 이후부터는 ServiceAccount 생성시 자동으로 Token이 생성되지 않습니다!

 

네, 1.24 버전 이후의 k8s를 사용한 클러스터로 작업중이라면 
ServiceAccount와 함께 수동으로 Token을 위한 Secret을 생성해야 합니다. 
예를 들어 보겠습니다. 

apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: default
  name: drone-bot

1.24 버전까지는 위와 같이 ServiceAccount를 생성하면 
`drone-bot-token-j13b7`와 같은 스타일의 토큰이 자동으로 생성되었습니다. 

1.24 이후 버전부터는 보안 강화를 위해 토큰을 자동으로 생성하지 않습니다. 
따라서 아래와 같이 별도로 Secret 오브젝트를 생성해 줘야 합니다. 

apiVersion: v1
kind: Secret
metadata:
  name: drone-bot-secret
  namespace: default
  annotations:
    kubernetes.io/service-account.name: drone-bot
type: kubernetes.io/service-account-token

이렇게 하고나면 ServiceAccount에 대한 Token을 획득할 수 있습니다. 

% k get secret drone-bot-secret -n default
NAME               TYPE                                  DATA   AGE
drone-bot-secret   kubernetes.io/service-account-token   3      15s

% k get secret drone-bot-secret -n default -o yaml
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTi...
  namespace: ...
  token: ZX...
...

왜 자동으로 Token이 생성되지 않는지 한참 헤메였는데...
알게 모르게 k8s 버전이 1.25로 바뀌었는데 그걸 모르고 클러스터 만들고 삽질을 했었네요...
여러분은 삽질하지 마시라고 공유해 드립니다!

 

728x90
728x90

드문드문 k8s를 사용하다보니 매번 반복적으로 쉬운 것들을 잊곤 합니다.
오랜만에 또 새로운 클러스터를 새로운 환경에 만드느라 삽질하는 요즈음,
잊었던 것들을 또 하나씩 적어 볼까 합니다.

ServiceAccount 생성

이번에는 CI/CD 연동 등을 통해 k8s 클러스터에 대한 작업을 같이 수행하고 있습니다. 
빌드 배포시마다 k8s 환경이 잘 구축되어 있는지를 점검하려는 욕심에 그만...
그래서 ServiceAccount 의 생성이 필요해졌습니다.

요약하면... 걍 만들면 됩니다.
그래도 우리는 선언적으로 만드는게 좋겠죠.
네, drone을 쓰려는 중입니다 ㅎㅎ

apiVersion: v1
kind: ServiceAccount
metadata:
  name: drone-bot

 

Role 선언

이번엔 ServiceAccount에 연결할 Role을 정의해 봅시다.
Role을 정의하려다 보니 apiGroups와 해당되는 resources
그리고 사용 가능한 verbs가 뭐가 있는지 또 헤메기 시작합니다. 

% kubectl api-resources -o wide

kubectl로 위 명령을 입력하면 필요한 모든 것들이 쫘아악~
필요한 권한과 대상 리소스에 대한 내용을 확인하면 됩니다. 
늘 느끼는 거지만 APIVERSION은 왜 이리 아스트랄한지...

몇 가지 골라서 일단 때려 넣습니다.
보안 헛점은 일단 고려치 않습니다 ㅎㅎ
필요한 동사들은 조금 더 발라내 봐야겠네요. 

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: drone-bot
rules:
  - apiGroups: [""]
    resources: ["configmaps", "secrets", "services", "namespaces"]
    verbs: ["get", "list", "create", "update", "patch", "delete"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "create", "update", "patch", "delete"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingresses"]
    verbs: ["get", "list","watch", "create", "update", "patch", "delete"]

복수형에 주의하시고, 
엉뚱한 apiGroups에 넣지 않도록 주의합시다!

ServiceAccount와 Role을 연결하는 RoleBinding

이렇게 두개의 k8s 객체를 만들었으니 이제 연결해야겠죠?
RBAC으로 권한 부여를 할 것이기 때문에 RoleBinding을 하면 됩니다. 
이름이 다 drone-bot이라 헷갈릴 수 있지만...

metadata.name 은 RoleBinding의 이름이고
subjects.kind[].name은 생성한 ServieAccount의 이름이며
roleRef.name은 생성한 Role의 이름입니다. 

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: drone-bot
subjects:
  - kind: ServiceAccount
    name: drone-bot
roleRef:
  kind: Role
  name: drone-bot
  apiGroup: rbac.authorization.k8s.io

 

그럼... 이제 생성해보러...

728x90
728x90

얼마전 회사 공식 유튜브 채널에서 개발자 밋업 영상을 찍었습니다.
근래에 회사 공식 유튜브나 블로그에 뭔가 기여한 기억도 없고 하여
겸사겸사 "NGINX 쿡북" 2판 번역서 출간 홍보도 할겸 전격 촬영에 임했습니다.

유튜브 라이브로 진행되는 회사 관련 액티비티는
신년대응 관련해서 진행했던 세션 이후로 간만이라.. 감회가 새로웠습니다.
재미있는 것은 이 영상을 찍은 이후에도 회사내에서 NGINX 관련한 이슈들에 난입할 계기가 있었고
세션에서 했던 이야기들이 헛되지 않았구나 하는 생각을 했었습니다 ^^;

아무쪼록 재미있게 봐주시면 좋겠습니다.
이것도 벌써 찍은지 2주가 넘어가는..ㅎㅎ

 

728x90

+ Recent posts