분류 전체보기 236

sqlalchemy logging 옵션 끄기

sqlalchemy를 처음 사용할 때에는 계속 나오는 로그들을 어떻게 없앨 수 있을지에 대해서 이리저리 구글링을 많이 해보게 된다. 스택오버플로우를 봐도 잘못된 답변들도 보이고, 결국 30분간 이리저리 삽질을 하다가 나름의 답을 찾아냈다. 아래 코드와 같이 4개의 토픽에 대해서 로그레벨을 ERROR로 설정해놓으면 데이터베이스 에러로 인한 상황을 제외하고는 모든 디버깅 로그나 info 로그가 다 필터링되게 된다. import logging from typing import Any, Generator # from sqlalchemy.sql import text from sqlalchemy import Column, Integer, MetaData, Table, Text, select from sqlmodel..

Python/sqlalchemy 2024.01.02

쿠버네티스에서는 스왑이 기본적으로 비활성화 된다?

알다시피, 운영체제는 더 많은 프로세스들이 메모리를 더 안정적으로 사용할 수 있도록 하기 위해 덜 사용되는 데이터를 메모리에서 디스크로 옮기는 스왑(swap)을 지원한다. 이를 통해 서버는 더 안정적으로 메모리를 관리할 수 있게 되는 것이다. 그런데, 쿠버네티스의 경우 기본 정책 상 swap을 비활성화시키도록 정책이 설정되어 있다. 물론 23년 8월 경에 알파 릴리스의 형태로 swap이 활성화된 형태로 파드를 생성할 수 있게 하는 설정이 추가되긴 했으나 아직은 프로덕션 환경에서 사용하기에는 시기상조로 보인다. 쿠버네티스에서 스왑 비활성화를 더 선호하는 이유는 "보안"이 가장 큰 이유로 볼 수 있다. 별도의 네임스페이스를 만들어서 마운트시킨 쿠버네티스 환경에서 굳이 격리된 데이터를 디스크로 스왑하는 작업은..

pod가 초기화 상태에서 멈춰서 시작을 못하는 경우

쿠버네티스의 파드는 여러 개의 컨테이너를 가질 수 있다. 이 중, "init containers"라고 불리는 컨테이너들이 있는데, 이 컨테이너들은 파드의 초기화를 담당한다. 파드가 생성되고 시스템적 격리가 이루어지는 초기단계에 수행되어야 할 작업들을 명시하기 위해 사용된다. Init container들이 모두 정상적으로 끝나야 초기화가 완료되고 main container 들이 실행되게 된다. 만약 init container가 실패 상태로 종료되고 restart 정책이 Never로 설정되어있다면 파드 자체의 초기화 실패로 단정하고 파드의 상태를 Failed로 바꾸게 된다. 또한, init container가 어떠한 이유로 인해 종료되지 않거나 restart 정책이 꼬여서 무한 재시작을 하고 있는 상태라면 ..

Shell에서 return문이 일반 언어에서의 return문과 다른 점

DevOps 등의 목적으로 shell로 함수등을 만드는 경우가 많이 생기게 된다. 이렇게 함수로 코드를 짜게 된다면 "return"문을 사용하는 경우 역시 발생하게 된다. 사실 shell의 return은 일반 프로그래밍 언어에서 사용되는 return문과 근본적인 차이가 있는데, 바로 숫자 타입만 반환이 가능하다는 것이다. 예를 들어, 셸 스크립트로 문자열을 반환하는 함수를 짜게 되면 return문으로는 문제를 해결할 수가 없다. 반환할 문자열의 종류가 미리 정해져 있다면 프로그래밍 언어에서의 enum을 사용하는 것처럼 각 문자열을 미리 숫자 코드로 디자인해두고, 적절한 숫자값을 리턴하는 함수를 구현하면 된다. 만약, 이러한 방법론이 아니라 순수하게 문자열 자체를 반환해야 한다면 return이 아니라 ec..

Shell script 2023.12.30

adb를 통해 앱 로그 얻기

adb logcat을 사용하면 앱 로그를 손 쉽게 채취할 수 있다. 물론, adb로 연결해서 로그를 얻기 위해서는 타겟 스마트폰이 "개발자 모드"가 활성화된 상태여야만 한다. # 연결된 스마트폰의 모든 로그 출력 adb logcat # 'Info' 이상인 'ActivityManager' 태그가 있는 로그 메시지와 # 'Debug' 이상인 'MyApp' 태그가 있는 로그 메시지를 제외하고 # 모든 로그 메시지를 억제 adb logcat ActivityManager:I MyApp:D *:S # 로그 출력 결과를 "log.txt" 파일로 저장 adb logcat -d > log.txt 우선순위 (로그 레벨) adb logcat은 아래와 같이 7가지 종류의 레벨(우선순위)를 가지게 된다. V: Verbose(가..

Android 2023.12.30

맥북에서 minikube 쿠버네티스 서비스 접근이 안될 때

쿠버네티스 공부를 로컬호스트 상에 Kubernetes 클러스터 구축을 위해 가장 많이 사용되는 방식은 아마 도커와 minikube를 사용하는 방법일 것이다. 이 minikube를 사용한 클러스터의 경우 가장 큰 단점으로는 NodePort나 LoadBalancer와 같은 서비스에 대해서 external IP가 제대로 할당되지 않아서 서비스를 만들어도 외부 클러스터에서 접근이 잘 안되는 문제일 것이다. 이 문제를 처음 접하는 사람들은 "혹시 서비스가 제대로 만들어지지 않았나?"나 "kube-proxy"에 뭔가 문제가 있나?" 등의 삽질을 많이 하게 될 것이다. 실제로 필자 역시 처음 minikube를 사용해서 쿠버네티스 공부를 할 때에는 문제를 제대로 파악하지 못해서 몇시간동안 삽질을 했던 적이 있다. 서비..

데이터 관리 패턴

데이터는 중앙화된 방식과 분산 방식 이렇게 2가지 방법으로 관리할 수가 있다. 1. 중앙 데이터 관리 중앙 데이터 관리 (centralized data management) 방식은 전통적인 데이터 중심 애플리케이션에서 가장 자주 사용하는 방식이었다. 모든 데이터를 단일 중앙 집중형 데이터베이스에 저장하는 방식으로 데이터를 저장 및 처리하도록 하는 것이다. 이 방식은 DB의 정규화가 가능하며, 아주 높은 데이터 일관성을 제공하는 등의 장점이 있다. 여러 컴포넌트가 데이터베이스의 모든 테이블에 접근할 수 있기 때문에 중앙 데이터 스토어가 여러 테이블에 데이터를 빠르게 저장하고 가져올 수 있다. 반면, 데이터베이스와 애플리케이션들 간에 강한 연관성이 생기게 되기에 Cloud-Native하지 못한 방법으로 취급..

다중 컨테이너 배포 패턴

마이크로서비스 아키텍처나 Auto-Scaling, 그리고 컨테이너 기술이 발전하면서 컨테이너 배포 패턴 자체도 다양한 방법론들이 나오게 되었다. 1. 사이드카 패턴 (Sidecar pattern) 다양한 기능을 추가 및 강화하기 위해 Pod 내에 추가적인 컨테이너를 추가하는 기법 2. 앰버서더 패턴 (Ambassador pattern) 사이드카 패턴의 세부 패턴 메인 컨테이너의 프록시 역할을 해주는 서브 컨테이너를 추가하는 패턴 nginx 등을 통해 프록시를 옆에 두는 패턴부터 REST API와 gRPC 사이의 컨버터 역할을 해주는 컨테이너 등 다양한 기법 존재 3. 어댑터 패턴 (Adaptor pattern) 사이드카 패턴의 세부 패턴 메인 컨테이너의 output 값이나 형태를 변형하는 컨테이너를 추가..

Container 2023.12.25

Subdomain에 대해 쿠키 공유하도록 설정하기

웹 서비스를 개발하다보면 상태 관리를 위해 세션이나 쿠키를 많이 사용하게 된다. 그렇게 서비스가 커지다보면 서브도메인이 많이 생기게 되는데, 모든 서브도메인에서 공통으로 가지는 상태가 생기게 될 것이고, 이를 처리하기 위해 쿠키를 서브도메인들 전체에 대해 공유하도록 만들어야 하는 상황이 발생하게 된다. 각 서브도메인 서비스마다 cookie getter와 setter API를 일일히 만드는 방법도 있겠지만, 서비스의 수가 많아지다보면 일일히 관리하기 어려워지게 되고, 시나리오가 더 복잡해지게 될 것이다. 그렇다면 도메인과 서브도메인 전부에 쿠키를 공유시키는 가장 간단한 방법은 무엇이 있을까? 답은 HTTP 쿠키에 대한 RFC 문서에 있다: https://datatracker.ietf.org/doc/html..

Web 2023.12.19

Request가 실질적으로 처리되기까지의 여정

백엔드에 요청을 보낼 때 대부분의 경우 요청의 처리 측면에 집중하는데, 이는 실제로는 마지막 단계에 불과하다. 요청이 처리될 준비가 되기까지 훨씬 더 많은 일이 일어나게 된다. 이를 6단계로 나누면 각 단계는 이론적으로 전용 스레드나 프로세스에 의해 실행될 수 있다. 거의 모든 백엔드, 웹 서버, 프록시, 프레임워크, 심지어 데이터베이스도 이 모든 단계를 수행해야 하며, 각 단계마다 다른 방식으로 수행한다. 1. Accept 요청은 종종 연결(TCP/QUIC)을 통해 전송되며 백엔드에서 연결을 수락해야 한다. 클라이언트가 포트 443에서 서버에 연결하면 서버 OS 커널에 의해 3방향 핸드셰이크가 완료되고 연결이 수신기 대기열에 배치되게 되는데, 이 대기열을 수락 대기열(accept queue)이라고 부른..

DevOps/백엔드 2023.10.31