
백엔드
Flask
파이썬으로 작성된 마이크로 웹 프레임워크의 하나로, 상대적으로 가볍고 빠르며 손 쉽게 사용 할 수 있다.
StackOverflow 질문 수: 56039
Github Stars : ★ 69200
사용 기업

큐피스트

파운트

바로고

디셈버앤컴퍼니

버즈빌

에이비일팔공

위대한상상

두나무

원티드랩

카카오

스켈터랩스

스포카

쏘카

번개장터

링글

네오사피엔스

에이모

두들린
더 보기
여기어때컴퍼니
자동화를 생활화 합시다. — Online DDL 테스트 자동화 이야기
자동화를 생활화합시다. — Online DDL 테스트 자동화 이야기안녕하세요, 여기어때컴퍼니 SRE팀 인턴 제이드입니다.오늘은 제가 여기어때컴퍼니에 인턴으로 합류하게 된 이후에 진행했던 주요 프로젝트 중 하나인 ‘온라인 DDL 테스트 자동화 프로젝트’에 대해 이야기하려고 합니다.본격적으로 프로젝트를 소개하기에 앞서, 온라인 DDL이라는 개념이 익숙하지 않으신 분들을 위해 간단히 개념부터 설명드리겠습니다.출처: Chat GPT 제작 이미지온라인 DDL이란?온라인 DDL(Online Data Definition Language)은 데이터베이스의 테이블 구조를 변경하거나, 인덱스를 추가하거나 삭제하거나, 컬럼을 수정하는 작업을 서비스 중단 없이 수행할 수 있는 방식입니다. 이러한 기능은 24시간 운영되는 서비스에서 데이터베이스 작업으로 인한 다운 타임을 방지하기 위해 필수적입니다. 참고로 저희가 사용하는 Amazon Aurora MySQL에서는 온라인 DDL이 기본적으로 활성화되어 있어, 스키마 변경 작업 시 적절한 알고리즘을 자동으로 선택해줍니다.온라인 DDL 작업을 실행하기 위해서는 작업 방식에 따라 Instant, Inplace, Copy라는 세 가지 알고리즘 중 하나가 사용됩니다. 이 알고리즘들은 각각 작업 시간과 데이터베이스 리소스 소모 측면에서 차이를 보이며, 작업 성격에 따라 적합한 방식이 선택됩니다.Instant 알고리즘은 테이블의 메타데이터만 수정하여 작업을 완료하는 방식입니다. 데이터 자체에는 전혀 영향을 주지 않기 때문에 가장 빠르고 리소스를 거의 사용하지 않습니다. 메타데이터는 테이블의 구조나 속성을 정의하는 정보로, 테이블 이름, 열의 정보, 기본값 등이 포함됩니다. 예를 들어, 테이블에 새로운 열(column)을 추가하거나 열의 기본값을 변경하는 작업이 Instant 알고리즘으로 처리됩니다. 데이터 복사가 없기 때문에 테이블 락이 발생하지 않으며, 서비스에 미치는 영향도 없습니다.Inplace 알고리즘은 기존 데이터를 복사하지 않고, 데이터를 유지한 상태에서 작업을 수행합니다. 예를 들어, 테이블에 새로운 열을 추가하되 기존 데이터에 기본값을 적용하거나 열의 데이터 타입을 변경하지 않는 작업이 해당됩니다. 데이터 복사가 없기 때문에 Copy 알고리즘보다 리소스를 적게 사용하며, 작업 도중 일부 락이 발생할 수 있지만 테이블 전체가 잠기지는 않아 서비스에 미치는 영향이 최소화됩니다. Inplace 알고리즘은 작업 성능과 안정성을 동시에 고려해야 하는 경우에 적합한 방식입니다.Copy 알고리즘은 원본 데이터를 새로운 테이블로 복사한 후, 변경 사항을 적용하는 방식으로 동작합니다. 작업 완료 후 기존 테이블은 삭제되고 새로 복사된 테이블이 원본 테이블을 대체하게 됩니다. 이 과정은 데이터의 양에 따라 시간이 오래 걸리고, 스토리지와 I/O 리소스를 많이 사용하게 됩니다. 특히, 대량의 데이터나 트래픽이 많은 환경에서는 성능 저하가 발생할 수 있으므로 신중하게 사용해야 합니다. Copy 알고리즘은 데이터 구조와 내용에 모두
awsauroradb
flask
mysql
slack
SK텔레콤
On-premise에 Kubernetes 구축하기(with Netapp Storage)
최근 Kubernetes 을 이용하기 위해서는 Public Cloud 에서 제공하는 PaaS 상품을 이용하는게 일반적이지만,기존 On-premise 데이터센터에 여유있는 리소스를 활용 할 수 있는 경우와 또한 Private한 Kubernetes를 환경을 구축해야하는 경우는여전히 On-premise 환경에서의 Kubernetes 구성에 대한 요구가 존재 합니다.아래 작성된 내용은 현재 On-premise 환경에서 운영하고 있는 Kubernetes 구축 내용을 command (kubeadm 활용) 단위로 정리 하였습니다.안타깝게 최신버전이 아닌 Kubernetes 1.26 기반으로 작성되어 있으나, 1.26 버전 이후 부터는 구성 방법에 대한 큰 변화가 없기 때문에 최신 버전에서도 활용 가능합니다.또한 레포지토리 및 메뉴얼 링크, 주요 depolyment yaml 파일 링크는 최신 및 현재 활용 할 수 있는 버전으로 내용 업데이트 하였습니다.On-premise 환경 Kubernetes 운영에 있어 HA 측면 가장 고민스러운 PV (Physical Volume)과 서비스 LB (Load Balancer) 을 Netapp사의 trident를 이용하여Nettap NAS (ONTAP NAS) 와 Metal LB를 이용하였습니다. 인증은 자체 구축한 LDAP 서비스를 이용하였으며, Flask를 이용한 인증처리 서버를 간단히 구현한 내용을 포함하였습니다.K8s 내부 이중화를 위해서는 On-premise의 L4 스위치 장비를 이용하였습니다.from flask import Flask, request, jsonify import pprint import requests import ldap from requests.auth import HTTPBasicAuth app = Flask(__name__) @app.route('/', methods=['POST']) def auth(): # User가 kubernetes API Server에 인증 요청 # Kubernetes API Server 가 사전에 정의 된 Webhook Server로 REST 요청보낸것을 받아오는 코드 tokenReview = request.json print(" ") # Webhook Server에 연동되어있는 인증 서버에서 인증 결과 받아옴 tokenReview['status'] = external_auth_LDAP(tokenReview) pprint.pprint('---return result---') pprint.pprint(tokenReview) # Webhook Server에서 Kubernetes API Server로 인증결과 보냄 return jsonify(tokenReview) # 외부 인증 시스템 def external_auth_LDAP(tokenReview): try: user, pw = tokenReview['spec']['token'].split (':') # 예제에서 생성했던 도메인 정보 (/etc/hosts 에 localhost로 명시했음) ldap_address = "ldap://172.27.xxx.xxx:389" ldap_object = initialize_ldap(ldap_address) ldap_result = authenticate(ldap_object, ldap_address, user, pw) print('result: %s'%(ldap_result)) if ldap_result == True: status = {} status['authenticated'] = True status['user'] = { 'username': user, 'uid': user, 'groups': ['apollo'] } else : status = {} status['authenticated'] = False except: status = {} status['authenticated'] = False return status def authenticate(ldap_object, ldap_address, user_name, password): try: ldap_object.simple_bind_s(user_name, password) except ldap.INVALID_CREDENTIALS: ldap_object.unbind() return False except Exception as e: print(e) return False return True def initialize_ldap(ldap_address): ldap_object = ldap.initialize(ldap_address) return ldap_object if __name__ == '__main__': app.run() EOF systemctl ldap-webhook
flask
kubernetes
SK텔레콤
[네트워크] Flask는 어떻게 동작하는가 2편(with WSGI)
그동안 계속해서 네트워크 관련 Low Level을 알아 보았습니다.이번에는 Python에서 많이 사용되는 WebFrameWork인 에 대해서 알아보는 두번째 시간입니다!는 서버를 이용하고, 는 를 이용한다고 했습니다.하지만 이걸로만은 부족하죠?분명 Flask는 다양한 url_rule, EndPoint를 설정하고, 하나의 서버에서 이 EndPoint를 모두 다룰 수가 있습니다.그러면 어떻게 다양한 EndPoint를 다룰 수 있는지 이 부분에 대해서 알아보겠습니다.tutorial을 보면 의 를 Decorator로 사용해서EndPoint를 추가하는 것을 볼 수 있습니다.그럼 의 를 찾아가 볼까요?위 패턴은 Decorator 함수 이면서 매개변수를 받는 경우입니다.그렇기 때문에 rule = endpoint를 String으로받음 일것 같지만가 Decorator로 한번더 감싸진것을 볼 수 있습니다.이때 는 같은 파일에서 정의 되어 있습니다.: 를 통해서 받아들인 매개변수를 , 로 받아들임: 의 매개변수 f로 들어가서 에서 사용됨Decorator를 풀어서 보면, 아래처럼 실행 될겁니다.조금 복잡하게 구성되어있지만, 여튼 위와같은 순서로 작동하게 됩니다.결국 중간에 을 통과하면서 url 리스트와 상호작용 후함수 자기자신이 다시 나오게 되는 구조입니다.이제 을 볼 차례입니다.• None Decorator를 달아도 함수 자체는 변하지 않는다.• None 이 과정에서 을 통과한다• None Object를 만들어서 Object에 추가한다.• None Flask는 자체적으로 라는 dict에 를 저장한다결국 돌아가서 객체가 werkzeug Server에서 어떤 역할을 하는지를 알아야합니다,그래서 다시 로 돌아가 보겠습니다.이전 포스팅에서 werkzeug 서버는 Requests를 처리할 때 를 상속받은 를 사용한다고 했습니다.그리고 이때 에서 , 을 호출하면서 Requests 처리가 시작됩니다.(이 내용 역시 Python의 CGI에서 다뤘었죠)이때 지난 포스팅에서 넘어갔던 부분을 다시 살펴보겠습니다.에서 를 호출하고, 호출된 함수를 실행시키면서 Response를 보내게 되어 있습니다.그럼 이 를 좀더 세밀하게 살펴볼 시간 입니다.일단 먼저 함수 내부에서 정의한 함수를 통해서 requests 처리가 시작됩니다.이때 이라는 것을 넣어주게 되는데이 는 의 생성자에서 설정이 됩니다.그러면 최초로 라 Call된 시점으로 가 보겠습니다.여기서 를 통해서 시작이 되는데이때 인것을 알 수 있습니다.그래서 에는 가 들어가게 될겁니다.그리고 의 정체가 바로 가 되게 되죠.이제 좀더 나가볼까요?이때 application_iter를 통해서 작성해야할 HTTP Msg를 받아오게 됩니다.이제 다시 로 가보겠습니다.위에서 보면 (Dict로된 환경변수 모음)이 의 매개변수로 들어가고을 활용해서 를 생성합니다.여기서 를 통해서 단서가 잡히게 됩니다.근데 위에서 를 했던거 기억 나시나요?이부분을 다시 살펴보겠습니다.에서 사용하던 이 만들어지는 부분을 확인할 수 있습니다.그러면 를 통해서 url정
flask
SK텔레콤
[네트워크] Flask는 어떻게 동작하는가 1편 (with WSGI)
그동안 계속해서 네트워크 관련 Low Level을 알아 보았습니다.이번에는 Python에서 많이 사용되는 Web FrameWork인 Flask에 대해서 알아보겠습니다.대신, 어렵지않게 튜토리얼과 함께 말이죠!Flask는 Python의 대표적인 입니다.각 , 마다 동작할 함수를 미리 기술해두고이 기술된 함수에 맞춰 requests를 처리하는 패키지 입니다.이러한 방식은 나 도 동일한 구조를 갖고있죠.이러한 Flask가 어떻게 동작하는지 튜토리얼과 함께 알아 볼겁니다.그럼 Flask 공식 github에서 제공하는 Tutorial을 간단히 살펴보겠습니다.최초로 를 만들고여기에 decorator를 사용해서 routing을 추가합니다.그리고 마지막에 을 사용해서 웹서버가 동작하게 됩니다.일단 는 아래처럼 상속구조를 가지고 있습니다.이때 다행히도(?) 에서 을 바로 찾을 수 있습니다.Flask는 자체적으로 의 을 사용하는 것을 볼 수 있습니다.그럼 이제 잠깐 를 알아보러 가보겠습니다.는 를 wrapping한 패키지 입니다.Flask에 사용되는것으로 유명하지만, 자체적으로 webserver를 띄울 수가 있습니다.사용패턴을 보면 알 수 있지만, server에 application을 집어넣어주는 방식이여턴 werkzeug에서 사용되는 을 한번 봐보겠습니다.이때 이 정확이 어떤 type인지 알수가 없는 상태 입니다.코드상으로 보면 역시 에 포함됩니다.이때 소스코드에서 _typeshed라는것이 등장합니다.그래서 에서 이 정의되어 있고, type과 일치하는 것을 볼 수 있습니다.다시 돌아가보면, 내부에서 를 사용하는 상황 입니다.는 thread와 process정보에 따라 다른 ServerClass를 제공해 줍니다.이때 에 대한 코드를 봐 볼까요?이제 wsgiref를 어떻게 사용하는지 보이시나요?이전 WSGI포스팅 1편에서 보았듯WSGI는 를 실행하면서 를 이용해서 Client의 requests를 받아들이고받아들인 requests를 를 사용해서 처리합니다.werkzeug가 wsgiref와의 차이점은정도가 되겠습니다.이후에 requests를 처리할때는 와 유사하게 를 상속받아서 사용하기 됩니다.이때 을 처리할 때 내부의 를 사용합니다.여기까지 어떻게 Flask 서버가 동작하는지 알아 보았습니다.하지만 여기까지만 봐서는 와 차이점을 알기 어렵습니다.이때 decorator를 통해서 다수의 endpoint를 다룰 수 있게 됩니다.이 내용은 다음 시간에 이어서 다룹니다!
flask
연관 기술 스택

Django

FastAPI