logo
기술 블로그
logo
Kubernetes의 ConfigMap 변경을 자동 반영하는 GitOps 구성하기
ConfigMap 변경을 자동으로 반영하는 GitOps 구성을 하기 전까지, 우리 팀은 다음과 같은 방식으로 작업을 진행하고 있었습니다.개발자들이 ConfigMap에 추가하거나 수정해야 할 값이 생기면,제가 ArgoCD와 연결된 Git 저장소 내 ConfigMap 정의 파일을 직접 수정하고, 커밋한 뒤, 관련 파드를 수동으로 재시작(rollout restart)해주는 방식이었죠.이 작업은 표면적으로는 단순해 보이지만, 운영팀 전체 리소스의 반복적인 소모를 유발하고 있었고, 개발자 입장에서도 빈번한 요청을 전달하는 데 부담이 따를 수밖에 없었습니다.이러한 불편함을 줄이고, 더 나아가 자율적인 설정 관리가 가능하게 만들 수 없을까 고민하게 되었습니다.그래서 저는 다음과 같은 질문을 중심으로 접근을 시작했습니다:• None 우리가 이미 보유한 기술 스택으로 해결할 수 있는 문제인가?• None 개발자들이 직접 ConfigMap을 컨트롤할 수 있는 방식은 무엇인가?• None ConfigMap이 수정되었을 때, 자동으로 관련 파드를 재시작할 수 있는 툴이나 프로젝트가 존재하는가?여러 대안을 비교해본 결과, 우리 팀의 GitOps 구조에 가장 잘 맞는 해법은 Reloader + Argo CD 조합이었습니다.주요 이유는 별도의 커스텀 로직 없이도 단순하게 적용 가능하고, DevOps팀이 직접 개입하지 않아도 개발자들이 설정을 변경했을 때 곧바로 반영된다는 점이었습니다.Reloader를 간단히 설명드리자면, Reloader는 Kubernetes에서 ConfigMap이나 Secret 리소스에 변경이 감지되면,해당 리소스를 참조하고 있는 Deployment나 StatefulSet을 자동으로 재시작해주는 컨트롤러입니다.저희 팀은 이미 Kustomize + Argo CD 조합으로 GitOps 기반의 배포 환경을 운영하고 있었고,애플리케이션 리소스들과 함께 ConfigMap도 하나의 배포 단위로 포함되어 있었습니다.하지만 이 구조에서는 ConfigMap만 수정하려 해도 전체 애플리케이션 리소스를 함께 변경해야 했기 때문에, 설정 관리의 유연성이 떨어지고 커밋 단위도 무거워지는 문제가 있었습니다.그래서 저는 먼저 ConfigMap을 분리했고, ConfigMap만 별도로 관리할 수 있도록 GitOps 구조로 변경했습니다.변경 후 개발자분들은 직접 ConfigMap을 수정하면, Argo CD를 통해 해당 변경이 자동으로 동기화되고,Reloader가 이를 감지하여 관련 Deployment가 자동으로 재시작되는 것을 확인할 수 있었습니다.글로만 보면 다소 이해가 안될 수 있기 때문에, 그림을 보면서 다시 설명드리겠습니다.저희는 먼저 ConfigMap을 별도의 Git 저장소로 분리했고, Argo CD가 해당 저장소를 바라보도록 설정했습니다.그리고 Reloader가 클러스터 내 ConfigMap 리소스를 watch하도록 구성했으며, 이후에는 ConfigMap 값에 변경이 생기면,이를 참조하고 있는 리소스를 자동으로 rollout restart하도록 설정했습니다.example 네임스페이스에서 사용되는 ConfigMap들을 Kustomization으로 관리할 수 있도록 설정합니다.ConfigMap에 reloader.stakater.com/match: "true" 어노테이션을 추가하여, Stakater Reloader가 이 ConfigMap의 변경을 감지할 수 있도록 합니다.ArgoCD에서 ConfigMap 리소스를 관리할 수 있도록 kustomize 경로를 지정하여 자동 동기화가 가능하게 구성합니다.해당 Deployment가 참조 중인 ConfigMap 변경을 감지할 수 있도록 reloader.stakater.com/search: "true" 어노테이션을 추가합니다.이번 구조 개선을 통해 ConfigMap 변경 작업이 더 이상 번거로운 수작업이 아닌, GitOps 기반으로 자동화되었습니다.비록 작은 구조적 변화였지만, 개발자와 운영자 모두의 부담을 크게 줄일 수 있었고, GitOps의 진정한 장점을 팀원들과 함께 체감할 수 있는 계기가 되었습니다.앞으로도 이런 작지만 실용적인 개선을 꾸준히 이어가 보려 합니다.
SK텔레콤
·
오늘
logo
Go로 만드는 실시간 음성 챗봇: OpenAI Realtime API를 가장 쉽게 쓰는 법 (Go routine + Go channel)
우리는 다양한 상황에서 음성으로 AI와 대화하고 있습니다. 대부분의 음성 챗봇은 사용자의 입력이 끝나야 다음 단계가 진행되는 순차 처리 방식입니다.• None STT (Speech-to-Text): 사용자의 음성을 텍스트로 변환• None LLM (Large Language Model): 변환된 텍스트를 기반으로 AI 응답 생성• None TTS (Text-to-Speech): 생성된 텍스트 응답을 다시 음성으로 합성이 구조는 음성을 → 텍스트로 → 생각하고 → 다시 음성으로 바꾸는 방식으로 동작하고 있습니다.그런데 이 구조에는 두 가지 한계를 가지고 있습니다.• None 챗봇이 음성으로 응답하는 동안에는 사용자가 말을 시작할 수 없습니다.• None 즉, 사람이 대화 중 끼어들 듯 말하는 barge-in 기능이 지원되지 않아, 실제 대화처럼 자연스럽게 주고받는 흐름이 어렵습니다.• None 음성 입력 → 텍스트 변환(STT) → 응답 생성(LLM) → 음성 합성(TTS) 과정을 순차적으로 거치기 때문에, 각 단계의 처리 시간이 누적되며 전체 응답 속도에 영향을 줍니다.사람과의 자연스러운 대화처럼, 말이 겹치고 바로 반응하는 진짜 실시간 대화란 어떤 모습일지에 대해 고민해보게 되었습니다.여기서 말하는 ‘실시간’은 단순히 빠른 응답이 아니라, 사용자와 챗봇이 동시에 말하고, 끊고, 반응하는 자연스러운 상호작용을 의미합니다.이러한 경험이 가능할지 탐색하는 과정에서, 우리는 OpenAI의 Realtime API를 테스트해보며 그 가능성을 살펴보게 되었습니다.OpenAI Realtime API는 멀티모달 모델(GPT-4o 및 mini) 을 기반으로 한 초저지연(ultra low-latency) 양방향 인터페이스입니다.WebSocket 또는 WebRTC 연결로 텍스트와 오디오를 동시에 스트리밍하고, 실시간 음성 대화를 구현할 수 있게 만들어졌습니다. (Speech-to-Speech)OpenAI Realtime API는 다음 두가지 연결 방식을 지원합니다.우리는 기존의 백엔드 시스템에서 관리할 수 있도록 WebSocket을 활용하여 서버 - 서버 연동을 테스트해보았습니다.클라이언트에서 실시간으로 음성 데이터를 서버로 전송하면, 서버는 이를 OpenAI Realtime API에 전달하고, 응답 결과(음성 또는 텍스트)를 다시 실시간으로 클라이언트에 전달하는 구조입니다.서버는 이 과정에서 중계와 함께 DB에서 프롬프트 설정을 조회하거나, 로그를 저장하는 등 비즈니스 로직도 함께 처리할 수 있습니다.그리고 OpenAI Realtime API와는 WebSocket 연결을 유지한 채, 스트림 기반으로 상시 통신하고 있습니다.4. Go Channel과 Goroutine으로 WebSocket 양방향 스트림을 쉽게 다뤄보자우리가 목표로 했던 것은 WebSocket 기반 OpenAI Realtime API와의 실시간 양방향 통신을 안정적이고 명시적으로 다루는 것이었습니다.WebSocket을 사용하면 다음과 같은 이유로 구현이 복잡해질 수 있는데요.• None 하나의 스트림에서 동시에 송수신이 일어나야 합니다. (별도의 스레드, 비동기 핸들링 구조 필요)• None 연결 종료, 네트워크 오류, 타임아웃 등 다양한 실패 케이스가 송수신 양쪽에서 다르게 발생하므로 예외 처리가 분산될 수 있습니다.• None 연결 상태를 mocking하거나 제어하기 어렵습니다.이를 위해 Go에서 제공하는 채널(channel) 과 고루틴(goroutine) 을 활용했습니다.Go의 chan(채널)은 Goroutine 간 데이터를 주고받을 수 있는 안전한 통신 수단입니다.간단히 말하면, 두 개의 흐름 사이에 데이터를 흘려보내는 파이프 같은 개념입니다.goroutine Go의 초경량 스레드로, 함수 하나를 동시에 실행시키는 비동기 작업 단위입니다.수천 개를 띄워도 메모리 부담이 거의 없기 때문에, WebSocket처럼 동시에 여러 작업이 일어나는 환경에서 특히 유용합니다.그래서 우리는 Go의 chan과 goroutine 조합을 사용해 읽기와 쓰기, 에러 처리, 종료 흐름을 명확히 분리하고 구조화했습니다.그 결과, 내부 로직은• None 채널에서 꺼내는이처럼 데이터 흐름을 명확히 분리한 덕분에 WebSocket의 읽기/쓰기 처리뿐 아니라 에러 핸들링과 종료 처리까지도 직관적으로 구현할 수 있었고, 테스트 작성 역시 수월해졌습니다이후 서비스 로직에서는 session의 In과 Out 채널을 통해 메시지를 주고받기만 하면 되므로, WebSocket 처리에 직접 관여하지 않고도 실시간 흐름을 간결하고 편리하게 구현할 수 있습니다.이번 글에서는 OpenAI Realtime API가 무엇인지, 그리고 어떤 상황에서 활용할 수 있는지부터 이를 Go의 goroutine과 channel을 활용해 실시간으로 연결하는 구조까지 함께 살펴보았습니다.복잡할 수 있는 WebSocket 스트림도, Go의 채널을 활용하면 직관적인 흐름으로 추상화할 수 있다는 것을 확인할 수 있었고,이를 통해 실시간 음성 응답 흐름을 안정적이고 효율적으로 구현할 수 있었습니다.Realtime API는 현재 베타(Beta) 단계로, 지속적으로 발전 중인 기술입니다.실제 서비스에 안정적으로 적용하기 위해서는 프롬프트 설정, 보이스 옵션, 그외 여러 파라미터 등 다양한 기능들을 상황에 맞게 테스트하고, 최적의 조합을 찾아가는 과정이 필요했습니다.하지만 그만큼 앞으로 더 많은 기능이 추가되고, 더 나은 성능과 커스터마이징 옵션들이 제공될 것이라는 기대도 큽니다.Go의 channel과 goroutine은 이러한 실시간 스트리밍 구조에 매우 강력한 도구입니다.이번 예제를 바탕으로, 여러분의 프로젝트에서도 채널 기반의 구조를 다양하게 시도해 보시길 추천드립니다. 😄
SK텔레콤
·
오늘
logo
데이터는 흐른다, 연결될 준비가 되었다면
네이버 사내 기술 교류 행사인 NAVER ENGINEERING DAY 2025(5월)에서 발표되었던 세션을 공개합니다. 발표 내용유저 세그먼트를 손쉽게 정의하고, 이를 다양한 액션 채널(Braze, IDS, GAM 등)과 자동 연동할 수 있는 네이버 웹툰의 Cohort System을 소개합니다. 조건 기반 필터링, ML 모델 연동 등 다양한 방식으로 세그먼트를 만들고, 중복 제거 로직과 함께 효율적으로 활용할 수 있습니다. 시스템 구조와 기술 스택, 실제 마케팅 활용 사례까지 함께 공유하며, 데이터에서 인사이트, 나아가 액션까지의 연결을 어떻게 자동화했는지를 설명합니다.강의 대상데이터 엔지니어 / 백엔드 엔지니어: 데이터 흐름 자동화, 시스템 구조에 관심 있는 분ML 엔지니어 / 데이터 사이언티스트: ML 결과를 실시간 타겟팅에 적용하고 싶은 분마케터 / PM: 타겟 유저 추출과 액션 전환까지의 전체 흐름을 이해하고 싶은 분목차Episode 1: 데이터 추출, 아직도 수작업으로 하시나요?반복과 오류, 그리고 비효율의 문제Episode 2: 웹툰의 코호트 시스템코호트 시스템의 구조와 흐름Episode 3 : Data 연결: 코호트에서 액션으로ML 모델IDSBrazeGAMEpisode 4 : Data 확장: 코호트에서 코호트로코호트 간 중복 제거 기능Episode 5: 캠페인 사례로 본 Cohort System의 효과코호트 시스템은 어떻게 쓰여질까? NAVER ENGINEERING DAY란? NAVER에서는 사내 개발 경험과 기술 트렌드를 교류를 할 수 있는 프로그램이 많이 있습니다. 그중 매회 평균 70개 이상의 발표가 이루어지는 NAVER ENGINEERING DAY를 빼놓을 수 없는데요. 2016년부터 시작된 ENGINEERING DAY는 실무에서의 기술 개발 경험과 새로운 기술과 플랫폼 도입 시 유용하게 활용될 수 있는 팁 등을 공유하며 서로 배우고 성장하는 네이버의 대표적인 사내 개발자 행사입니다. 올해 진행된 NAVER ENGINEERING DAY 2025(5월)의 일부 세션을 공개합니다.
네이버
·
오늘
logo
AI와 글쟁이의 동행: 코드 주면 API 레퍼런스 써드려요
기술 문서는 늘 부족합니다. 특히 좋은 기술 문서가 부족하죠.테크니컬 라이터는 좋은 기술 문서를 쓸 수 있지만, 사내 프로젝트를 모두 담당하기에는 수가 턱없이 모자랍니다. '개발자 글쓰기 교육'으로 그 간극을 메워보려는 시도도 있지만, 과연 교육만 들으면 모든 개발자가 기술 문서를 잘 쓰게 될까요?글쎄요, 저는 회의적입니 다. '잘 쓰는 방법을 몰라서'는 개발자가 기술 문서를 쓰지 않는 원인 중 하나일 뿐, 전부가 아니니까요. '시간'이나 '관심' 같은 외부적 원인은 교육으로는 해결하지 못합니다.문서 엔지니어로서, 저는 이 문제를 '개발자 교육'보다 '엔지니어링'으로 풀어보려고 노력해 왔습니다. 프로세스를 통한 강제화, 도구를 이용한 자동화로요. 생성형 AI가 글 쓰는 직무를 대체할 것이라는 예측도 있지만, 이런 관점에서 볼 때 도큐먼트 엔지니어에게 AI가 반드시 경쟁자인 것만은 아니더군요. 오히려 기존의 한계를 극복하게 해주는 기회에 가깝죠. 비유하자면, 테크니컬 라이터가 한 땀 한 땀 공들여 문서를 만들어 내던 가내수공업 방식을 공장형 자동 생산으로 바꿀 기회랄까요.LINE Plus의 Document Engineering 팀은 이런 마음가짐으로 AI를 꾸준히 활용해 왔고, 덕분에 그 아이디어를 시험해 볼 기회를 얻었습니다.LY 그룹은 업무에 생성형 AI를 도입하는 데 적극적입니다. 그 일환으로 주요 개발 단계에서 생성형 AI를 활용하는 프로젝트를 진행 중인데요. 대상 작업 중 하나가 문서화입니다.저희 팀은 프로젝트를 시작하면서 문서화 생산성을 높이겠다는 목적 아래 개발 단계에서 가장 필요한 문서가 무엇일지 한참 고민했습니다(프로젝트 자체 요구 사항을 참고해서요). 몇 가지 아이디어가 있었고, 그중 소스 코드를 이용하면서 개발자나 사용 자에게 모두 영향을 미치는 API 레퍼런스 문서에 적용해 보기로 했습니다.소스 코드를 설명하는 기능은 GitHub Copilot 같은 코딩 어시스턴트가 이미 잘하고 있는데 '뭘 더 하려는 것일까?'하는 의문이 생기실 수도 있겠네요. 아쉽게도 코딩 어시스턴트로는 해결하지 못하는 문제가 몇 개 있습니다.더불어 프로젝트마다 API 문서 형식도 다르고 배포하는 곳도 달라서 참고하기 어렵다는 개발 팀 의견도 있었습니다. 코딩 어시스턴트는 이것도 해결하지 못하죠. 따라서 저희는 '사내 정보를 참고해서 사내 스타일에 맞는 API 주석을 작성하고, 이를 레퍼런스로 만들어 한곳에서 배포하기'를 목표로 삼아 프로젝트를 시작했습니다.저희 팀은 기술 문서를 검토하고 다국어화한 경험이 많습니다. 이미 몇몇 프로젝트에서는 문법, 표현, 스타일 일관성을 확인하는 용도로 프롬프트를 만들어 AI를 활용하고 있고요.사내 스타일 가이드에 맞춰 일관된 톤과 스타일을 유지하려면 꽤 긴 프롬프트가 필요합니다. 여기에 프로그래밍 언어별로 상세한 API 주석을 작성하는 방법과 용어 정보까지 더했더니 LLM이 몇몇 지시를 놓치기 시작했습니다(LLM도 지시가 많으면 기억력이 떨어지나 봅니다). 그러잖아도 사내 머신 러닝 팀 전문가의 도움을 받고 있었던 터라 개선 방안을 여쭸더니, 실행 단계를 나누고 단계별로 수행할 프롬프트를 분리하라고 하시더군요.처음에는 아래와 같이 세세하게 단계를 나눴습니다.
라인
·
하루 전
logo
신용대출 찾기 서비스 제휴사 mock 서버 개발기
신용대출 찾기 서비스는 다양한 제휴사의 대출 상품을 연동하여, 고객이 보다 편리하게 대출 상품을 탐색하고 신청할 수 있도록 돕는 서비스입니다.이번 글에서는 신규 제휴사 연동 이후 제휴사의 테스트 서버가 유효한 응답을 주지 않거나, 특정 케이스를 테스트하기 어려운 상황을 어떻게 해결했는지, 그리고 이를 위해 설계한 mock 서버를 소개하고자 해요.신규 제휴사 연동 이후 다음과 같은 문제들이 반복적으로 발생했어요.• None 특정 퍼널 또는 고객 조건에 맞는 테스트 데이터 확보의 어려움• None 테스트 과정에서 실제 제휴사 서버로부터 유효한 응답을 받기 어려운 상황이러한 문제들은 QA 및 신규 기능 개발 효율을 떨어뜨릴 뿐 아니라, 서비스 출시 일정에도 영향을 주었습니다. 이를 해결하기 위해 사용자, 제휴사, 퍼널 단위로 정밀하게 동작을 제어할 수 있는 mock 서버를 설계했어요.본격적인 설명에 앞서, 대출 도메인과 관련된 주요 용어를 간략히 정리할게요.• None : 은행, 저축은행, 보험사 등 대출 상품을 제공하는 금융기관• None : 고객 정보를 활용해 대출 금리, 한도 등을 간단히 확인하는 행위• None : 가심사 결과를 바탕으로 고객이 특정 상품에 대해 대출을 신청하는 행위• None : 제휴사가 고객 정보를 활용해 대출을 실행하고 자금을 입금하는 행위기능적 / 비기능적 요구사항은 아래와 같았어요.mock 서버는 다음과 같은 구성요소로 설계되었습니다.신용대출 찾기 서비스는 mock 동작 여부나 mock 데이터 생성 시 필요한 유저 정보를 클라이언트 요청의 헤더를 통해 주입받습니다. 이렇게 하면 비즈니스 로직에는 전혀 영향을 주지 않고, 테스트를 유연하게 제어할 수 있어요.• None RestTemplate에는 인터셉터를 통해 요청마다 헤더를 추가할 수 있어요. 아래는 유저 ID와 원장 ID를 주입하는 예시입니다.• None 에 등록하면, 모든 제휴사 요청에 자동으로 헤더가 포함됩니다.• None WebClient에서는 을 활용해 헤더를 주입해요. 아래는 동일한 목적의 필터 예시입니다.• None 와 같이 등록해주면 돼요.모든 설정값은 DB 테이블에서 관리하여 유연성을 확보했어요.• None• None 콜백 을 N 초 후에 받을 것인지• None 특정 퍼널 에 대해 어떤 mock 응답을 받을 것인지 등정의된 정보를 사용해 mock 응답 을 생성합니다.mock 서버에서는 실제 제휴사처럼 콜백 응답을 지연하여 전송하는 기능이 필요합니다. 이를 통해 비동기 응답을 테스트할 수 있도록 지원하며, 실제 서비스 환경을 더 현실감 있게 시뮬레이션할 수 있어요.예약은 다음과 같이 두 단계로 구성됩니다.• None 가심사 조회나 대출 신청 API 호출 시점에,• None 각 요청에 대해 몇 초 후 콜백을 호출할 지 결정되며, 이 설정은 유저 설정( )에 정의된 값을 사용합니다.• None 필드에 실행 시점을 기록합니다.• None mock 서버에서는• None 를 사용해 콜백 API 요청을 실제로 전송합니다.mock 응답은 실제 제휴사 응답과
비바리퍼블리카
·
하루 전
logo
AWS Summit Seoul 2025 스케치
안녕하세요. 여기어때컴퍼니 iOS개발팀 샐리입니다.지난 5월 14일 AWS Summit Seoul 2025 — Industry Day에 참석했습니다.예상대로 올해 행사에서는 생성형 AI가 가장 화두였습니다. 다양한 세션들을 듣고 Expo도 둘러보았는데요. 생성형 AI가 산업 전반에 얼마나 빠르게 적용되고 있는지 체감하고 인사이트도 얻을 수 있었습니다.코엑스에 도착하니 벌써 많은 분들이 부스 체험을 하고 계셨습니다. 저도 얼른 참가자 등록을 하러 갑니다.행사 입장을 위해 네임택을 수령하러 왔습니다. 세련된 공간 연출과 조명 덕분에 마치 콘서트에 온 듯 했네요. 규모에서부터 압도되는 느낌이었고 어떤 프로그램들이 기다리고 있을지 기대감이 커졌습니다.AWS Summit Seoul 행사는 세션과 Expo로 이루어져있습니다. 모두 다 해보려니 시간이 약간 부족하기도 했지만 세션과 Expo를 모두 즐기고 알차게 보내고 왔습니다.세션1. 여행 goes AI! AWS 생성형 AI 없이는 살아남을 수 없어!여기어때가 여행/숙박 앱이다보니 자연스레 관심이 가는 주제였습니다.RAG 기반의 업무용 생성형 AI 챗봇인 Amazon Q에 대해서 알게 되었는데요. Amazon Q로 사내에 도움이 되는 챗봇을 만들어보면 재밌을것 같다는 생각이 들었습니다.AI is not going to replace humans, but humans with AI are going to replace humans with AI. — Karim Lakhani말 그대로 직역해보자면 AI는 사람을 대체할 수는 없지만 AI를 사용하는 사람이 AI를 사용하지 않는 사람을 대체할 것이다.AI가 오래 전부터 연구되어 온 기술이긴 하지만 AI기술이 보편화되는 것은 살짝 먼 이야기라고 느껴졌었는데요. Chat-GPT의 등장으로 판도가 완전히 바뀌었죠. 이제는 누구나 AI를 사용하고 활용할 수 있게 되었. Chat-GPT가 등장한게 지금으로부터 불과 몇년 전이지만 현재는 AI가 없는 일상이나 업무는 거의 상상할 수 없을 정도니까요. 단순한 정보 검색을 넘어서 문서와 코드 작성, 아이디어 구상 등 실질적인 생산성 도구가 되어 우리의 삶을 더 편리하게 해주고 있습니다.저도 AI가 인간의 모든 능력을 완전히 대체할 수는 없다고 생각합니다. 하지만 이제는 AI 없이 일하는 게 비효율이 되어버린 시대로 바뀌었다는 생각이 들었습니다. 앞으로는 AI를 어떻게 잘 효율적으로 활용하느냐가 큰 관건이 될 것 같습니다.2. Amazon Bedrock을 이용한 이미지 검색서비스의 혁신저는 작년 사내 해커톤에서 GenAI를 활용한 챗봇을 주제로 참가했었는데요. 간단하게 설명드리면 Google Vision API로 숙소 이미지 메타데이터를 태깅하고 색인 DB를 구축하여 이미지 기반 숙소 검색 기능을 제공하는 챗봇이었습니다. 해커톤에서 만든 것과 실제 비즈니스 방식이 어떻게 어떻게 다를지 궁금했습니다.게티이미지코리아에서는 키워드 기반의 검색을 자연어 검색이 가능한 기능을 구현했다고 합니다. 사용자가 이미지를 업로드하면 Amaz
여기어때컴퍼니
·
2일 전
기술 블로그 더 보기
Copyright © 2025. Codenary All Rights Reserved.