본문 바로가기

분류 전체보기189

WSL2 - SSH 설정 및 접속 SSH 설정 및 접속 1. 호스트 키 설정 ssh-keygen -A 명령으로 호스트 키가 /etc/ssh 경로에 생성되도록 한다. admin@LAPTOP-O7OIHPIJ:~$ sudo /etc/init.d/ssh stop * Stopping OpenBSD Secure Shell server sshd [ OK ] admin@LAPTOP-O7OIHPIJ:~$ sudo ssh-keygen -A 2. ssh-config 설정 admin@LAPTOP-O7OIHPIJ:~$ sudo vi /etc/ssh/sshd_config … # To disable tunneled clear text passwords, change to no here! PasswordAuthentication yes … admin@LAPTOP-O.. 2022. 5. 30.
Window10 WSL2 설치 필수 구성 요소Windows 10 버전 2004 이상(빌드 19041 이상) 또는 Windows 11을 실행 시작 → 설정 → 시스템 → 정보 → Windosw 사양 확인 BIOS 설정1. BIOS 가상화컴퓨터 사양에 따라 BIOS 진입 및 가상화 방법이 다르다. 나는 Lenovo 노트북을 사용하고 있으므로 F1을 누르고 BIOS로 진입한다. Configuration 메뉴에서 Intel Virtual Techonology를 Enabled 활성화한다. (BIOS에 따라 메뉴가 다를 수 있음) 2. Hyper-V 활성화재부팅 후에 제어판 > 프로그램 및 기능 > Windows 기능 켜기/끄기 메뉴로 진입한다. Hyper-V를 활성화시킨다. Hyper-V 메뉴가 없을 때는 https://yscho03.tist.. 2022. 5. 30.
GitLab Runner 설치 및 등록 설치 환경ubuntu 20.04.1 설치 방법1. 리포지토리 등록amd64, arm, arm64 아키텍처가 있는 amd64로 한다.root@master:~# curl -LJO "https://gitlab-runner-downloads.s3.amazonaws.com/latest/deb/gitlab-runner_amd64.deb" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 414M 100 414M 0 0 1909k 0 0:03:42 0:03:42 --:--:-- 1029k2. 패키지 설치root@master:~# dpkg -i gitlab-runner_amd64.de.. 2022. 5. 25.
Git Password 저장 방법 Credential 정보 저장 credential 정보를 저장하여 반영구적으로 인증 절차가 생략된다. git config credential.helper store --global 옵션을 설정하여 모든 프로젝트에 적용할 수 있다. git config --global credential.helper store Cache 저장 임시로 저장할때 사용한다. 기본적으로 15분 동안 인증 절차를 요구하지 않는다. git config credential.helper cache timeout 옵션으로 지정이 가능하다. (초 단위) git config credential.helper 'cache --timeout=3600' 참고 https://git-scm.com/docs/git-credential-cache 2022. 5. 18.
VirtualBox에 Docker 환경 구성 구성 환경 CentOS 7 (Minimal Version) Image VirtualBox 구성 방법 1. 이미지 다운로드 http://isoredirect.centos.org/centos/7/isos/x86_64/ 첫번째 링크를 클릭한다. CentOS-7-x86_64-Minimal-2009.iso를 선택한다. 2. 가상 머신 만들기 새로 만들기를 클릭한다. 하기와 같이 머신 폴더 및 Linux 종류를 설정한다. 여유롭게 공간을 사용하기 위하여 50GB를 지정하였다. 3. 가상 머신 환경 구성 부팅 순서에서 불필요한 플로피 제거한다. 4. CentOS 설치 4. 포트 포워딩 [root@localhost ~]# yum install -y net-tools ... [root@localhost ~]# ifcon.. 2022. 5. 11.
Window 10 Home Hyper-V 활성화 방법 Window 10 Home Hyper-V Windows 10 Pro, Enterprise 및 Education 64비트 버전에서만 사용할 수 있고 Home 버전에서는 사용할 수 없다. Docker Desktop for Windows 설치를 위해서는 반드시 Hyper-V를 지원하는 OS가 필요하지만 Home 버전에서는 Hyper-V 기능을 사용할 수 없는 탓에 Docker Toolbox(Virtual Box)를 이용한 가상화를 통해서만 Docker를 설치할 수 있다. 무작정 블로그나 여러 사이트를 가서 Window 10 Home에 Hyper-V 설치를 하려고 하면 아래와 같은 문구가 표시되는 것을 볼 수 있을 것이다. microsoft-hyper-v은 는 알 수 없는 기능 이름입니다. Hyper-V 설치 .. 2022. 5. 10.
GitLab 백업 및 복원 방법 애플리케이션 데이터 백업은 데이터베이스, 모든 리포지토리 및 모든 첨부 파일을 포함하는 아카이브 파일을 생성한다. 백업을 생성한 GitLab의 버전 및 유형(CE/EE)과 정확히 동일한 버전 으로만 백업을 복원할 수 있다. 요구사항 # Debian/Ubuntu sudo apt-get install rsync # RHEL/CentOS sudo yum install rsync GitLab 백업 GitLab은 다음을 포함하여 전체 인스턴스를 백업하는 명령줄 인터페이스를 제공한다. 데이터 베이스 첨부 파일 Git 리포지토리 데이터 CI/CD 작업 출력 로그 CI/CD 작업 아티팩트 LFS 객체 Terraform 상태( GitLab 14.7에 도입 됨) Container Registry 이미지 GitLab 페이지.. 2022. 5. 10.
GitLab API를 활용한 마이그레이션 개요 BACKUP & RESTORE를 사용하여 파일을 활용하는 방법이 가장 간단한 방법이긴 하다. 하지만 회사 보안상이나 서버에 접근이 불가하거나 여러 가지 이슈들로 인하여 API를 활용하여 마이그레이션을 활용해야 하는 경우가 있다. 시나리오 GitLab (구서버 - old-gitlab.com) 에서 git clone 하여 로컬에 임의 디렉토리에 저장 localhost에서 GitLab (새로운 서버 - new-gitlab.com)로 push 준비사항 GitLab Group Acesss Token Python 3.x 마이그레이션 방법 1. GitLab Server Group Acess Token 발급 GitLab API를 활용하여 마이그레이션 하기 위해서는 Group에 접근할 Token을 발급한다. Gro.. 2022. 5. 9.
프론트엔드 모노레포 전략 모노레포(monorepo)란? 모노레포란 버전 관리 시스템에서 두 개 이상의 프로젝트 코드가 동일한 저장소에 저장되는 소프트웨어 개발 전략이다. 아래과 같은 프로젝트 구조를 보면 이해하기 빠를 것이다. 모노레포 장점 팀 간 협업 개선 모든 프로젝트가 동일한 리포지토리에 포함된다. 즉, 회사의 모든 사람이 코드를 보고 사용할 수 있으므로 공유 라이브러리를 더 쉽게 찾고 활용할 수 있다. 이는 협업 및 코드 재사용을 할 수 있어서 리소스를 절약할 수 있다. 간편한 종속성 관리 모노레포는 내부 및 타사 종속성 관리를 더 간편하고 수월하게 할 수 있다. 특정 버전의 종속성을 고정하여 업데이트가 필요할 때 전체 코드에서 변경 사항 및 이전 버전과의 호환성을 더 쉽게 테스트할 수 있다. 즉, 종속성의 취약점을 관리.. 2022. 5. 3.
OSGi에 대하여 알아보자 OSGi란? OSGi (Open Service Gateway initiative - 개방형 서비스 게이트웨이 이니셔티브) 프레임워크는 모듈형 소프트웨어 프로그램과 라이브러리를 개발 및 배포하기위한 자바 프레임 워크이다. 각 번들은 강하게 결합하고, 동적으로 로딩이 가능한 class, jar 그리고 명시적으로 외부 종속성을 선언하는 환경설정파일의 모음이다. 쉽게 이야기해서 OSGI는 번들 단위로 관리하고 실행할 수 있는 프레임워크를 말한다. OSGi 적용분야 이클립스 IDE OSGi 서비스 플랫폼은 홈게이트웨이 텔레매틱스 단말(예:BMW, SimensVDO), 모바일 단말 산업 자동화, 빌딩 자동화 PDA / 스마트폰 / 태블릿 등의 모바일 단말 그리드 컴퓨팅 백색가전 (예: BSH, 보쉬-지멘스 가전 합.. 2022. 5. 3.
Java OSGi Tutorial Github 소스 MathConsumer : https://github.com/yscho03/MathConsumer MathService : https://github.com/yscho03/MathService Tutorial (튜토리얼) 1. OSGi "MathConsumer" 생성 1-1. MathConsumer 프로젝트 생성 Activator Code package org.tutorial.helloosgi.mathconsumer; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { private static B.. 2022. 5. 3.
Java + Gradle을 사용하여 gRPC 서비스를 만들어보자 gRPC가 무엇인지 알아보기 전에 RPC가 무엇인지 알아보자. RPC란? RPC(Remote Procedure Call - 원격 프로시저 호출)는 다른 위치에서 클라이언트 요청을 통해 원격 프로세스를 실행하는 기술이다. RPC 사용의 여러가지 문제로 인해 개발자는 오늘날 대부분의 최신 분산 컴퓨팅 솔루션에서 RPC 사용을 피하고 REST 아키텍처를 선호하고 있다. RPC 문제점 RPC의 문제점은 무엇이길래 이렇게 사용을 안하게 되었을까? Sam Newman의 Building Microservices: Designing Fine-Grained Systems 는 마이크로서비스에서 RPC를 사용하는 3가지 이유가 여전히 의심스럽다고 언급했다. 주요 기술 결함으로는 다음과 같다. Java RMI와 같은 기술은 .. 2022. 4. 28.
s3cmd를 사용해서 Object Storage를 관리하자 s3cmd란? S3cmd 는 데이터 S3 호환 개체 저장소를 업로드, 검색 및 관리하기 위한 무료 오픈 소스 명령줄 도구 및 클라이언트이다. 명령줄 프로그램에 익숙하지만 초보자도 빠르게 배울 수 있을 만큼 간단한 고급 사용자를 위한 강력한 도구이다. 기본환경 python 3.x 이상 s3cmd 설치방법 1. s3cmd 설치 python만 설치되어 있다면 설치방법은 매우 간단하다. hadoop@hadoop-001:~$ pip install s3cmd Collecting s3cmd Downloading s3cmd-2.1.0-py2.py3-none-any.whl (145 kB) |████████████████████████████████| 145 kB 199 kB/s Collecting python-dateu.. 2022. 4. 26.
fabricJS - 이미지에 오버레이 포커스 개요 전체 이미지를 뿌옇게 오버레이 처리하고 네모 박스를 만들어서 포커스 효과를 주고 싶을 경우 jsfiddle : https://jsfiddle.net/yscho03/4uvjsb6L/ 전체 코드 var canvasWidth = 640, canvasHeight = 480; var canvas = new fabric.Canvas('my-canvas', { preserveObjectStacking: 'true', width : canvasWidth, height: canvasHeight }); canvas.setOverlayImage('https://placeimg.com/' + canvasWidth + '/' + canvasHeight + '/people', canvas.renderAll.bind(canv.. 2022. 4. 20.
모니터 선택기 - 셀인스텍 HDMI SWITCH 3TO1 선택기 구입 후기 회사에서 개발자에게 맥북을 보급하여 집에서 원래 사용하던 내돈내산 레노버 노트북 1대와 맥북 1대가 생겼다. 모니터 1대에 노트북 2대를 연결하여 사용하고 싶은데 예전에 일본에서 SI로 근무했던 겐바에서 사용했던 생각이 떠올라서 모니터 선택기(?) 등으로 검색을 해보았다. 다른 기능들은 필요없고 단순 모니터 1대만 전환해서 사용하고 싶기 때문에 쿠팡에서 저렴한 물건이 눈에 띄었다. 셀인스텍 HDMI SWITCH 3TO1 이었다. 셀인스텍 처음 들어보는 이름이었지만 구매후기 등 리뷰를 보니 나쁘질 않았기 때문에 바로 장바구니에 담았다. 노트북 2대를 연결하려면 별도로 HDMI 케이블 2개가 필요했기 때문에 넥시 8K UHD HDMI V2.1 모니터케이블도 같이 주문했다. 4월 17일 (일)요일에 주문해서 .. 2022. 4. 19.
JavaScript - 함수 다루기 함수는 2개 이하가 이상적이다 매개변수의 개수를 제한 하는 것은 함수 테스팅을 쉽게 만들어 주기 때문에 중요하다. 만약 매개변수가 3개 이상일 경우엔 테스트 해야하는 경우의 수가 많아지고 각기 다른 인수들로 여러 사례들을 테스트 해야한다. 3개 이상일 경우는 객체로 매개변수를 만들어서 사용하는 방법이 있다. BAD function createMenu(title, body, buttonText, cancellable) { // ... } GOOD function createMenu({ title, body, buttonText, cancellable }) { // ... } createMenu({ title: 'Foo', body: 'Bar', buttonText: 'Baz', cancellable: tr.. 2022. 4. 18.
JavaScript - 객체 다루기 Shorthand Properties 객체에 key-value을 할당 시 변수 그대로 할당을 하면 변수 이름 그대로 key가 되고 변수값 그대로 value로 값을 할당할 수 있다. 예제) BAD const name = "Tom"; const age = 20; const person = { "name" : name, "age" : age, }; console.log(person); // 결과 { age: 20, name: "Tom" } GOOD const name = "Tom"; const age = 20; // 다음과 같이 축약해서 사용 가능하다. const person = { name, age }; console.log(person); // 결과 { age: 20 name: "Tom" } Compute.. 2022. 4. 15.
JavaScript - 배열 다루기 Javascript의 배열은 객체다 Javascript 배열 요소 안에 key-value 값이나 함수를 설정해도 입력이 잘되는 것을 확인할 수 있다. const arr = [1, 2, 3]; arr[4] = 'test'; arr['property'] = 'value'; arr['obj'] = {}; arr['{}'] = [1, 2, 3]; arr['func'] = function () { return 'hello'; }; 호출해보면 key-value, 함수 모두 입력되어 있으며 console.log(arr); // output [ 0: 1 1: 2 2: 3 4: "test" func: ƒ () obj: {} property: "value" {}: (3) [1, 2, 3] length: 5 [[Protot.. 2022. 4. 15.
JavaScript - 분기 다루기 값,식,문 문법을 간과하는 경우가 있는데, 문법은 컴퓨터를 이해시켜야하기 때문에 중요하다. 값과 식과 문을 구분한다. // "값"이 들어가야하는 자리에 "식"이 들어감 (X) Hello World // 삼항연산자는 "값"으로 귀결되기 때문에 사용 가능 (O) Hello World () : 함수, 우선순위 {} : 값과 식만 들어가야함. 바로 리턴되는 분기문은 논리연산자를 사용해야한다. if (conditionOne) {return one;} // 간단한 연산을 활용한 방법 {conditionOne && one} 삼항 연산자 다루기 피 연산자가 조건, 참일 때, 거짓일 때 세개 인것을 잊지말자. 삼항연산자를 과도하게 중복해서 사용하는 경우를 피하자 1. if를 사용하여 조건을 나누자 2. else-if를 .. 2022. 4. 14.
JavaScript - 경계 다루기 min-max 미만, 초과 또는 이하, 이상인지 둘 중 하나로 해석될 가능성이 있다. const MIN_COUNT = 1; const MAX_COUNT = 100; 명시적으로 정의하기 위하여 LIMIT를 붙여서 다음과 같이 개선할 수 있다. const MIN_COUNT_LIMIT = 1; const MAX_COUNT_LIMIT = 100; begin-end 일반적으로 begin은 경계에 포함되고 end는 경계에 포함되지 않는 암묵적인 규칙이 있다. 2022-01-01부터 2022-01-10까지 포함될 것을 예측할 수 있다. function getDate(beginDate, endDate) { // some code } // 2022-01-01부터 2022-01-10까지 포함될 것을 예측할 수 있다. ge.. 2022. 4. 14.
JavaScript - 타입 다루기 타입 검사 typeof typeof는 피연산자를 검사해서 타입을 문자열로 반환하는 함수이다. Primitive value (원시적인 string, integer 등)는 typeof로 감별하기가 쉽지만 Reference value (참조되는 Object, Array 등)는 object라는 결과 값으로만 출력이 되므로 정확한 판별에 어려움이 있다. Object, Array 동일하게 object 결과를 가져오게 된다. typeof {} == 'object' // true typeof [] == 'object' // true instanceof instanceof 연산자는 생성자의 프로토타입 (prototype) 속성이 객체의 프로토타입 (prototype) 체인 어딘가 존재하는지를 판별할 때 사용한다. ins.. 2022. 4. 14.
JavaScript - 변수 다루기 함수 스코프 (Function Scope) vs 블록 스코프 (Block Scope) 함수 스코프 변수가 함수 내부에서 선언되면 해당 함수 내에서만 액세스할 수 있으며 해당 함수 외부에서 사용할 수 없다. 블록 스코프 if 또는 switch 조건이나 또는 for 또는 while 루프 내부에서 선언된 변수는 해당 특정 조건 또는 루프 내에서 액세스할 수 있다. 간단히 말해서 중괄호 안에 선언된 변수는 블록 범위 내에서 호출된다. var 는 함수 범위로 호출되며 let & const 는 특정 블록 내에 엑세스를 할 수 있다. let은 프로그램을 진행하면서 변경 가능하지만 const는 프로그램이 끝날 때까지 변경되지 않고 일정하게 유지된다. function hello() { if (true) { console.. 2022. 4. 14.
Spring Boot - Hello World 시작해보기 Hello World 시작 1. 패키지 생성 오른쪽 마우스로 New → Package을 클릭하여준다. 생성할 패키지 이름을 입력한다 . (점)으로 구분하면 된다. 2. 컨트롤러 클래스 생성 SapleController.java가 만들어졌으면 다음과 같이 코딩한다. 먼저 class 위에 @RestController 어노테이션으로 지정해주자. @GetMapping 어노테이션은 www.웹 주소/hello 요청을 처리하겠다는 의미이다. package com.sample.dev.api; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestC.. 2022. 4. 13.
Spring Boot 환경설정 환경설정 방법 1. STS 다운로드 https://spring.io/tools 접속하여 STS(Spring Tool Suite)을 다운로드하여 설치한다. 다운받은 jar 파일을 클릭하면 압축이 자동으로 해제된다. 2. OpenJDK 설치 https://jdk.java.net/java-se-ri/8-MR3 접속하여 다운로드한다. 윈도우 같은 경우 Windows 10 i586 Java Development Kit 을 클릭하여 다운로드하면 된다. 3. STS 실행 및 JDK 환경설정 3-1. STS 실행하고 워크스페이스 작업공간을 설정 3-2. Installed JREs 설정 Window → Perferences 를 클릭한다. 3-3. Compiler 설정 compiler를 다운받은 openJDK 버전에 맞게.. 2022. 4. 13.
하드웨어 - CPU 사양 보는 법 인텔 시리즈 예) Intel Core i5-11600K @3.90 GHz i5 - 등급 i는 인텔의 첫 글자의 의미이고 숫자가 높을수록 컴퓨터가 빠르고 좋다. 등급 용도 i3 저사양 보급용 i5 중~상 게임, 무난하게 프로그램 돌아감 i7 고사양 게임, 무거운 프로그램 (설계, 영상편집), 다중작업 i9 워크스테이션, 서버용 11 - 세대 (천의자리) 세대를 뜻하고 숫자가 높을수록 좋다. 현재 11세대가 출시되었는데 10세대의 단점을 많이 보완했다. 11세대 칩부터는 내장 그래픽을 포함하고 있다. 세대 모델명 1세대 린필드, 블룸필드, 클락데일 2세대 샌디브릿지 3세대 아이비브릿지 4세대 하스웰, 하스웰 리프레시, 데빌스캐년 5세대 브로드웰 6세대 스카이레이크 7세대 카비레이크 8세대 커피레이크 9세대 .. 2022. 4. 12.
Django vs Flask vs FastAPI 어떤 걸 사용해야 할까? 프레임워크 동향 아직까지는 github stars, Google Trends를 봐도 Django, Flask가 압도적인 추세이다. Django (장고) Django 프레임워크란? Django는 무료 오픈 소스인 python 웹 프레임워크이다. Adrian Holovaty와 Simon Willison이 2003년에 만들어졌다. Django 주요 목표 중 하나가 복잡한 데이터베이스 기반의 웹 사이트를 개발할 수 있도록 하는 것 적은 코드, 낮은 결합 및 재사용성, 연결 가능성 등 빠른 개발에 도움이 됨 Django 구축 사례 Instagram, Mozilla, Nextdoor 및 clubhouse와 같은 일부 대형 웹사이트에서 사용됨 Django 장점 MVC (모델-뷰-컨트롤러) 아키텍처를 활용한 데이터 베.. 2022. 4. 11.
원격 데스크톱 연결 비밀번호 변경 문제 원격 데스크톱 비밀번호 변경 문제 오류 메세지 코로나로 인한 재택근무가 시행됨에 따라 원격 연결을 하여 근무를 많이 하게 된다. 회사 보안상의 이유로 일정 기간에 따라 컴퓨터 비밀번호를 변경해야 되는데 일정 기간이 지나고 접속하려면 오류가 뜨면서 접속이 안된다. 이런다고 일정기간마다 출근할 수는 없는 노릇이다. 이럴 경우 해결 방법에 대해 알아보자. 해결방법 1. 원격 데스크톱 연결 시도 2. RDP 파일 저장 3. RDP 파일 수정 윈도우 notepad로 저장된 RDP 파일을 열고 맨 마지막 줄에 아래와 같이 추가한다. enablecredsspsupport:i:0 4. RDP 파일 클릭하여 접속 수정된 RDP 파일을 클릭하여 원격 데스크톱에 접속하여 비밀번호를 변경해주면 끝이다. 2022. 4. 11.
암호학 기본 개념 암호학의 기본 개념 1. 암호학의 정의 평문을 다른 사람이 알아볼 수 없는 형태의 암호문으로 만들고 특정한 비밀키를 알고 있는 사람이 다시 평문을 복원시킬 수 있는 기술 (cryptography)와 이를 제3자가 해독하는 방법을 분석하는 암호해독 (cryptographysis)에 관하여 연구하는 학문이다. 2. 암호학에서 사용하는 이름 앨리스와 밥 (Alice and Bob) : 송신자를 앨래스라고 하고 수신자를 밥이라 한다. 이브 (Eve) : 도청자를 의미한다. 소슥적인 공격자로 앨리스와 밥 사이에 이루어지는 통신을 도청하지만 통신 중인 메시지를 수정할 수 없다. 맬로리 (Mallory) : 악의를 가진 (malicious) 공격자를 의미한다. 메세지를 수정하고 수정한 메시지를 재전송할 수 있다. 트.. 2022. 4. 11.
Rest API란? REST란? REST (Representational State Transfer)는 웹의 장점을 최대한 활용할 수 있는 네트워크 기반의 아키텍처이다. 로이 필딩(Roy Fielding)의 2000년 박사학위 논문에서 소개되었다. HTTP와 URI 기반으로 자원에 접근할 수 있도록 제공하는 애플리케이션 개발 인터페이스이다. 기본적으로 개발자는 HTTP 메소드와 URI 만으로 인터넷에 자료를 CRUD 할 수 있다. REST 구성요소 메소드 리소스 모든 리소스를 명사로 표현한다. 다음과 같은 예제로 정의할 수 있다. 생성 유저를 생성한다. HTTP POST, http://sample.com/user { "name" : "yscho", "job" : "developer" } 조회 유저를 조회한다. HTTP PO.. 2022. 4. 11.
JVM 성능을 최적화 방법 JVM GC 최적화 JVM과 GC에 대해 지식이 있다는 가정하에 작성하였다. GC와 JVM 기초는 대한 기본 동작 방식 소개는 이전 페이지를 보면 나와있다. 1. 명시적 GC 알고리즘 설정 필요한 GC 알고리즘을 명시적으로 지정해주는 것이 좋다. 예를 들어 Java 8에서 기본 GC는 병렬 GC이고 Java 11에서 기본값은 G1GC이다. 이는 명시적으로 GC를 설정하지 않는 한 Java 8에서 Java 11로 업그레이드할 때 더 좋든 나쁘든 간에 사용자와 의지와는 상관없이 변경됨을 의미한다. -XX:+UseG1GC 2. Heap 크기 설정 -ms 와 -mx 옵션을 이용해서 힙 크기를 설정한다. 이러한 옵션으로 인하여 서버 안의 메모리의 최소, 최대를 조절할 수 있다. 간혹 -ms -mx와 같게 설정하시.. 2022. 4. 8.
728x90
반응형