시작하기 전에
- 실습에서는 정해진 기간 동안 Google Cloud 프로젝트와 리소스를 만듭니다.
- 실습에는 시간 제한이 있으며 일시중지 기능이 없습니다. 실습을 종료하면 처음부터 다시 시작해야 합니다.
- 화면 왼쪽 상단에서 실습 시작을 클릭하여 시작합니다.
Set up the Python application and necessary resources
/ 40
Containerize and publish the application to Artifact Registry
/ 10
Deploy the app to Cloud Run
/ 10
Find the issue and fix the application
/ 30
Add Error Reporting to the application
/ 10
Artifact Registry는 패키지 및 Docker 컨테이너 이미지를 저장하고 관리할 수 있는 단일 위치를 제공합니다.
Cloud Build는 Google Cloud에서 빌드를 실행하는 서비스입니다.
Cloud Run은 개발자가 Google의 확장 가능한 인프라에서 컨테이너를 실행할 수 있는 관리형 컴퓨팅 플랫폼입니다.
Google Cloud Observability는 애플리케이션에 대한 통합 모니터링, 로깅, 추적 관리형 서비스를 제공합니다.
Cloud 클라이언트 라이브러리는 애플리케이션에서 Google Cloud API를 호출하는 데 권장되는 방법으로, 애플리케이션에 사용 중인 프로그래밍 언어의 고유한 규칙과 스타일을 사용합니다. Cloud 클라이언트 라이브러리는 인증 및 재시도 로직을 포함하여 서버와의 하위 수준 통신을 처리합니다.
Google API는 인증 및 승인에 OAuth 2.0 프로토콜을 사용합니다.
Secret Manager를 사용하면 API 키, 비밀번호, 인증서, 기타 민감한 정보를 바이너리 blob 또는 텍스트 문자열로 저장할 수 있습니다.
이 실습에서는 Cloud Shell에서 Python 애플리케이션을 실행하고 Cloud Run에 애플리케이션을 배포합니다. 애플리케이션을 Cloud Run으로 이전할 때 발생하는 문제를 해결하고 Google Cloud 운영 제품군의 애플리케이션 개발 기능을 살펴봅니다.
이 실습에서는 다음 내용을 알아봅니다.
Google Skills 실무형 실습을 통해 시뮬레이션이나 데모 환경이 아닌 실제 클라우드 환경에서 직접 실습 활동을 진행할 수 있습니다. 실습 시간 동안 Google Cloud에 로그인하고 액세스하는 데 사용할 수 있는 새로운 임시 사용자 인증 정보가 제공됩니다.
이 실습을 완료하려면 다음이 필요합니다.
실습 시작 버튼을 클릭합니다. 실습 비용을 결제해야 하는 경우 결제 수단을 선택할 수 있는 팝업이 열립니다. 왼쪽에 있는 패널에서 이 실습에 사용해야 하는 임시 사용자 인증 정보를 확인할 수 있습니다.
사용자 이름을 복사한 다음 Google 콘솔 열기를 클릭합니다. 실습에서 리소스가 실행되며 계정 선택 페이지를 표시하는 다른 탭이 열립니다.
계정 선택 페이지에서 다른 계정 사용을 클릭합니다. 로그인 페이지가 열립니다.
연결 세부정보 패널에서 복사한 사용자 이름을 붙여넣습니다. 그런 다음 비밀번호를 복사하여 붙여넣습니다.
잠시 후 Cloud 콘솔이 이 탭에서 열립니다.
Google Cloud Shell은 다양한 개발 도구가 탑재된 가상 머신으로, 5GB의 영구 홈 디렉터리를 제공하며 Google Cloud에서 실행됩니다.
Google Cloud Shell을 사용하면 명령줄을 통해 Google Cloud 리소스에 액세스할 수 있습니다.
Cloud 콘솔의 오른쪽 상단 툴바에서 'Cloud Shell 열기' 버튼을 클릭합니다.
계속을 클릭합니다.
환경을 프로비저닝하고 연결하는 데 몇 분 정도 소요됩니다. 연결되면 사용자가 미리 인증되어 프로젝트가 PROJECT_ID로 설정됩니다. 예:
gcloud는 Google Cloud의 명령줄 도구입니다. Cloud Shell에 사전 설치되어 있으며 명령줄 자동 완성을 지원합니다.
출력:
출력 예시:
출력:
출력 예시:
이 작업에서는 Python 애플리케이션을 다운로드하고 앱의 현재 버전에서 사용되는 리소스를 만듭니다.
Firestore 데이터베이스를 만들려면 Cloud Shell에서 다음 명령어를 실행합니다.
Firestore 데이터베이스는 도서 및 사용자 프로필 데이터를 저장하는 데 사용됩니다.
Cloud Shell을 승인하라는 메시지가 표시되면 승인을 클릭합니다.
Cloud Storage 버킷을 만들려면 다음 명령어를 실행합니다.
Cloud Storage 버킷은 도서 표지 이미지를 저장하는 데 사용됩니다. 버킷은 균일한 버킷 수준 액세스 권한을 보유하며 공개 액세스 방지를 사용하지 않습니다.
버킷의 모든 객체를 공개적으로 읽을 수 있게 하려면 다음 명령어를 실행합니다.
승인에 OAuth 2.0을 사용하면 앱에서 Google 계정의 액세스 범위를 하나 이상 요청합니다. Google에서는 사용자에게 애플리케이션과 데이터를 공유하는 데 대한 사용자 동의를 구하는 동의 화면을 표시합니다.
Google Cloud 콘솔에서 탐색 메뉴()를 선택한 다음 API 및 서비스 > OAuth 동의 화면을 선택합니다.
시작하기를 클릭합니다.
앱 이름에 Bookshelf를 입력합니다.
사용자 지원 이메일에 학생 이메일을 선택합니다.
다음을 클릭합니다.
대상에서 내부를 선택하고 다음을 클릭합니다.
프로젝트에 대한 액세스 권한이 있는 사용자는 앱에 로그인할 수 있습니다.
실습 안내의 왼쪽 패널에서 사용자 이름을 복사합니다.
이메일 주소에는 복사한 사용자 이름을 붙여넣고 다음을 클릭합니다.
체크박스를 사용 설정하여 사용자 데이터 정책에 동의하고 계속을 클릭합니다.
만들기를 클릭합니다.
탐색 메뉴에서 브랜딩을 클릭합니다.
+ 도메인 추가를 클릭합니다.
승인된 도메인 섹션의 승인된 도메인 1에 cloudshell.dev를 입력합니다.
저장을 클릭합니다.
탐색 메뉴에서 데이터 액세스를 클릭합니다.
범위 추가 또는 삭제를 클릭합니다.
목록의 맨 위에서 openid 옆의 상자를 선택합니다.
필터에 userinfo.profile을 입력하고 Enter 키를 누른 후 .../auth/userinfo.profile 범위 옆에 있는 체크박스를 선택합니다.
필터에서 userinfo.profile 필터를 지우고 contacts를 입력한 다음 Enter 키를 누르고 .../auth/contacts 범위의 체크박스를 선택합니다.
업데이트를 클릭합니다.
민감하지 않은 범위 2개(openid 및 userinfo.profile)와 민감한 범위 1개(contacts)가 표시됩니다.
저장을 클릭합니다.
탐색 메뉴에서 클라이언트를 클릭한 후 + 클라이언트 만들기를 클릭합니다.
애플리케이션 유형에서 웹 애플리케이션을 선택합니다.
이름에 Bookshelf를 입력합니다.
승인된 리디렉션 URI에서 + URI 추가를 클릭합니다.
여기에 지정된 URI는 Google이 사용자 동의를 확보한 후 브라우저를 애플리케이션으로 다시 리디렉션할 때 사용됩니다.
리디렉션 URI를 가져오려면 Cloud Shell에서 다음 명령어를 실행합니다.
echo 명령어로 생성된 URI를 복사하여 URI 1에 붙여넣습니다.
만들기를 클릭합니다.
JSON 다운로드를 클릭하고 클라이언트 보안 비밀번호 JSON을 로컬 머신에 저장합니다.
클라이언트 보안 비밀번호 파일은 Google에서 앱을 인증하는 데 사용됩니다.
확인을 클릭합니다.
Cloud Shell에서 오른쪽 상단 툴바의 더보기()를 클릭한 후 업로드를 클릭합니다.
파일 선택을 클릭하고 클라이언트 보안 비밀번호 JSON 파일을 선택한 후 열기를 클릭합니다.
업로드를 클릭합니다.
이제 클라이언트 보안 비밀번호 JSON 파일을 home 디렉터리에서 사용할 수 있습니다. 이 파일의 내용은 OAuth 프로세스 중에 사용됩니다.
Secret Manager는 클라이언트 보안 비밀번호 JSON 파일을 저장하기에 권장되는 안전한 장소입니다.
Secret Manager API를 사용 설정하려면 Cloud Shell에서 다음 명령어를 실행합니다.
클라이언트 보안 비밀번호 파일의 이름을 바꾸려면 다음 명령어를 실행합니다.
보안 비밀을 만들려면 다음 명령어를 실행합니다.
이제 보안 비밀 bookshelf-client-secrets가 있으며 애플리케이션에서 액세스할 수 있습니다.
Flask 보안 비밀 키의 보안 비밀을 만들려면 다음 명령어를 실행합니다.
이 명령어는 20자리의 영숫자 비밀번호를 무작위로 생성한 후 보안 비밀 flask-secret-key에 저장합니다.
Cloud Storage 버킷에서 home 디렉터리로 Python 코드를 복사하려면 다음 명령어를 실행합니다.
bookshelf 디렉터리의 내용을 확인하려면 다음 명령어를 실행합니다.
7개의 Python 파일과 요구사항 파일, 6개의 템플릿 파일이 포함된 목록이 표시됩니다.
요구사항 파일의 종속 항목을 나열하려면 다음 명령어를 실행합니다.
요구사항 파일은 다음 종속 항목을 지정합니다.
요구사항 파일에 종속 항목을 설치하려면 다음 명령어를 실행합니다.
pip는 Python용 패키지 설치 프로그램입니다. 이 pip3 명령어는 Python 버전 3에서 사용할 수 있도록 requirements.txt 파일에 지정된 패키지를 설치합니다.
HTTP 서버를 시작하려면 다음 명령어를 실행합니다.
애플리케이션에 전달되는 환경 변수가 있습니다.
EXTERNAL_HOST_URL은 콜백 URL에 사용해야 하는 스키마와 호스트 이름을 지정합니다.이제 애플리케이션이 포트 8080에서 호스팅됩니다.
웹브라우저에서 애플리케이션을 실행하려면 웹 미리보기를 클릭하고 포트 8080에서 미리보기를 선택합니다.
브라우저에 새 탭이 열리고 애플리케이션이 실행됩니다. 이 페이지에는 모든 기존 도서의 목록이 표시됩니다. 아직 도서가 없습니다.
이 오즈의 마법사 도서 표지 이미지를 마우스 오른쪽 버튼으로 클릭하고 oz.png로 컴퓨터에 저장합니다.
+ 도서 추가를 클릭합니다.
도서를 추가하려면 로그인해야 하므로 Google로 로그인할 계정을 선택하라는 메시지가 표시됩니다.
학생 이메일을 클릭한 후 계속을 클릭합니다.
허용을 클릭합니다.
양식에 다음 정보를 입력합니다.
| 필드 | 값 |
|---|---|
| 제목 | 오즈의 마법사 |
| 저자 | 프랭크 L. 바움 |
| 출판일 | 1900년 |
| 설명 | 집으로 돌아갈 시간 |
표지 이미지에서 파일 선택을 클릭합니다.
다운로드한 파일(oz.png)을 선택하고 열기를 클릭합니다.
저장을 클릭합니다.
뷰 페이지로 돌아가면 도서 세부정보가 표시됩니다. 도서 세부정보는 Firestore 데이터베이스에 저장되고 표지 이미지는 Cloud Storage에 저장됩니다.
이메일 주소를 클릭합니다.
프로필이 표시됩니다. 언어 선택 컨트롤에 English가 표시되어야 합니다.
기본 언어를 스페인어로 변경한 후 저장을 클릭합니다.
도서 오즈의 마법사를 클릭합니다.
이제 뷰 페이지에 영어 원본 설명과 스페인어 번역이 모두 포함됩니다.
Cloud Shell에서 CTRL-C를 입력하여 애플리케이션을 종료합니다.
목표를 확인하려면 내 진행 상황 확인하기를 클릭합니다.
이 작업에서는 Cloud Build를 사용하여 애플리케이션을 컨테이너화하고 Artifact Registry에 게시합니다.
Artifact Registry 저장소를 만들려면 Cloud Shell에서 다음 명령어를 실행합니다.
저장소에는 애플리케이션 컨테이너가 보관됩니다.
저장소 세부정보를 표시하려면 다음 명령어를 실행합니다.
자체 Dockerfile을 만들어 애플리케이션을 Docker 이미지로 패키징할 수 있지만 Cloud Build는 빌드팩을 사용하여 컨테이너를 빌드할 수 있습니다.
Cloud Build를 사용하여 애플리케이션을 빌드하려면 다음 명령어를 실행합니다.
이 명령어는 ~/bookshelf 디렉터리에 있는 코드의 Docker 이미지를 빌드하고 Artifact Registry의 app-repo 저장소에 저장합니다.
빌드 목록을 보려면 다음 명령어를 실행합니다.
bookshelf 빌드가 나열됩니다.
목표를 확인하려면 내 진행 상황 확인하기를 클릭합니다.
이 작업에서는 애플리케이션을 Cloud Run에 배포한 다음 Cloud Run에서 애플리케이션을 테스트합니다.
애플리케이션을 Cloud Run에 배포하려면 다음 명령어를 실행합니다.
API를 사용 설정하라는 메시지가 표시되면 y를 입력합니다.
이 명령어는 방금 빌드한 이미지를 Cloud Run에 배포합니다. 사용자는 도서를 만들거나 수정하거나 삭제할 때만 로그인하면 되므로, 인증되지 않은 호출이 허용된다고 명시합니다. GOOGLE_CLOUD_PROJECT 환경 변수가 애플리케이션에 제공됩니다. 기본적으로 Cloud Run에서 사용할 수 없기 때문입니다.
Cloud Run이 애플리케이션을 배포합니다.
애플리케이션 URL을 가져오려면 다음 명령어를 실행합니다.
이전 명령어로 생성된 링크를 클릭합니다.
새 탭이 열리고 '서비스를 사용할 수 없음' 메시지(또는 다른 오류)가 표시됩니다.
애플리케이션이 제대로 실행되지 않습니다. 이유를 파악해야 합니다.
목표를 확인하려면 내 진행 상황 확인하기를 클릭합니다.
이 작업에서는 로그를 사용하여 문제를 해결합니다.
애플리케이션에 문제가 발생하면 Cloud Logging의 로그가 문제를 해결하는 데 도움이 될 수 있습니다.
Google Cloud 콘솔에서 탐색 메뉴()를 선택한 후 Cloud Run을 선택합니다.
bookshelf를 클릭한 후 로그 탭을 클릭합니다.
로그는 Cloud Run의 Bookshelf 애플리케이션에만 해당됩니다. 로그를 살펴보면 secretmanager.versions.access에 대한 permission denied 오류가 표시됩니다.
앱이 Cloud Shell에서 실행 중일 때는 애플리케이션이 로그인한 사용자의 사용자 인증 정보를 사용합니다. 학생 사용자는 Secret Manager의 항목에 액세스하고, Cloud Storage에 파일을 쓰고, Translation API를 호출할 수 있습니다.
서비스 계정을 제공하지 않으면 Cloud Run 애플리케이션은 Compute Engine 기본 서비스 계정을 사용합니다. 이 기본 서비스 계정에는 이러한 권한이 없습니다.
애플리케이션에 특정한 서비스 계정을 만들고, 이를 애플리케이션에 연결한 다음, 서비스 계정에 올바른 권한을 제공하는 것이 좋습니다.
애플리케이션의 서비스 계정을 만들려면 Cloud Shell에서 다음 명령어를 실행합니다.
아직 추가한 권한이 없습니다. 추가할 올바른 역할을 결정하려면 IAM 기본 역할 및 사전 정의된 역할 참조를 확인하세요. Secret Manager 역할에는 Secret Manager 보안 비밀 접근자 역할이 포함되며 이는 보안 비밀에 액세스하기 위한 최소 권한을 제공해야 합니다.
필요한 역할을 추가하려면 다음 명령어를 실행합니다.
권한은 Secret Manager, Cloud Translation API, Firestore, Cloud Storage에 대한 것입니다.
실행 중인 애플리케이션은 권한을 즉시 가져오지 않고 몇 분 내에 가져옵니다. 지연을 방지하기 위해 앱을 재배포할 수 있습니다.
서비스 계정으로 애플리케이션을 재배포하려면 다음 명령어를 실행합니다.
애플리케이션을 열려면 다음 명령어를 실행한 다음 링크를 클릭합니다.
오류가 표시될 수 있습니다. 이 오류가 발생하는 이유는 서비스 계정의 권한이 아직 전파되지 않았을 수 있기 때문입니다.
Cloud Run 서비스의 Bookshelf 로그를 살펴보면 권한 누락 또는 부족과 같은 오류가 표시될 수 있습니다. 권한이 전파되고 서비스 계정이 필요한 Google Cloud 서비스를 호출할 수 있을 때까지 앱은 실패합니다.
앱이 성공적으로 열릴 때까지 애플리케이션 탭을 닫고, 생성된 URL을 다시 클릭합니다.
권한이 전파되면 익숙한 도서 페이지가 표시됩니다.
애플리케이션에서 로그인을 클릭합니다.
로그인에 실패합니다.
오류 메시지는 액세스가 차단되었고, 앱에서 잘못된 요청을 전송했으며, 오류가 리디렉션 URI 불일치임을 나타냅니다. 이 오류는 OAuth 구성이 Cloud Run 서비스 URL이 아닌 cloudshell.dev에서만 실행되도록 설정되어 있기 때문에 발생합니다.
Google Cloud 콘솔에서 탐색 메뉴()를 선택한 후 API 및 서비스 > OAuth 동의 화면을 선택하고 브랜딩을 선택합니다.
+ 도메인 추가를 클릭합니다.
Cloud Shell에서 다음 명령어를 실행합니다.
이 명령어는 https:// 없이 애플리케이션의 URL을 빌드합니다.
도메인 이름을 클립보드에 복사한 후 승인된 도메인 2에 붙여넣습니다.
저장을 클릭합니다.
탐색 메뉴에서 클라이언트를 선택합니다.
OAuth 2.0 클라이언트 ID에서 Bookshelf를 클릭합니다.
승인된 리디렉션 URI에서 + URI 추가를 클릭합니다.
리디렉션 URI를 가져오려면 Cloud Shell에서 다음 명령어를 실행합니다.
echo 명령어로 생성된 URI를 복사하여 URI 2에 붙여넣습니다.
저장을 클릭합니다.
보안 비밀은 애플리케이션에 한 번만 로드되므로 애플리케이션을 재배포해야 합니다.
수정 사항을 적용하려면 다음 명령어를 사용하여 앱을 재배포합니다.
애플리케이션이 배포되면 다음 명령어를 실행하고 생성된 URL을 클릭합니다.
애플리케이션이 실행됩니다.
애플리케이션에서 로그인을 클릭한 후 동의를 제공하여 사용자를 로그인합니다.
이제 이메일 주소가 링크로 표시됩니다.
이메일 주소를 클릭합니다.
여전히 기본 언어는 스페인어입니다.
목표를 확인하려면 내 진행 상황 확인하기를 클릭합니다.
이 작업에서는 애플리케이션의 상태를 유지하는 데 사용할 수 있는 Google Cloud Observability의 몇 가지 기능을 살펴봅니다.
Error Reporting은 실행 중인 클라우드 서비스에서 발생한 오류를 집계합니다.
필요한 역할을 서비스 계정에 추가하려면 Cloud Shell에서 다음 명령어를 실행합니다.
Cloud Shell의 파일 편집기에서 ~/bookshelf/requirements.txt 파일을 엽니다.
다음 줄을 추가합니다.
이제 requirements.txt 파일은 다음과 같습니다.
파일을 저장합니다.
업데이트된 종속 항목을 설치하려면 다음 명령어를 실행합니다.
파일 편집기에서 ~/bookshelf/main.py 파일을 엽니다.
cloud_logging import 문 다음 줄에 다음 코드를 추가합니다.
/profile 엔드포인트의 하단에 다음 코드를 추가합니다.
/raiseerror 엔드포인트를 호출하면 Error Reporting에 오류를 발생시키고 오류 페이지로 리디렉션하여 오류를 시뮬레이션합니다.
파일을 저장합니다.
애플리케이션을 빌드하고 재배포하려면 다음 명령어를 실행합니다.
애플리케이션이 배포되면 다음 명령어를 실행하고 생성된 URL을 클릭합니다.
URL 끝에 /raiseerror를 추가한 다음 Enter를 클릭합니다.
오류 Intentionally Created Error가 표시된 애플리케이션 오류 페이지로 리디렉션됩니다.
URL에서 error를 raiseerror로 바꾸고 Enter를 클릭합니다.
애플리케이션 오류 페이지로 다시 리디렉션됩니다. 이러한 오류는 이후 단계에서 살펴봅니다.
목표를 확인하려면 내 진행 상황 확인하기를 클릭합니다.
Cloud Run 서비스 세부정보 페이지에는 서비스를 관리하는 데 도움이 되는 기본 제공 대시보드가 포함되어 있습니다.
Google Cloud 콘솔에서 탐색 메뉴()를 선택한 후 Cloud Run을 선택합니다.
bookshelf를 클릭합니다.
측정항목 탭이 표시됩니다.
지난 1일을 클릭하고 지난 1시간을 선택합니다.
측정항목 탭에는 지난 1시간 동안 발생한 서비스 호출 목록과 자동으로 수집된 측정항목 그래프가 표시됩니다.
로그 탭을 클릭합니다.
이 탭에서 Cloud Run 서비스의 모든 로그를 살펴볼 수 있습니다.
Google Cloud 콘솔 제목 표시줄의 검색 필드에 Logging을 입력하고 검색을 클릭한 후 Logging을 클릭합니다.
여기에서 모든 로그에 액세스할 수 있습니다.
모든 리소스 드롭다운 메뉴에서 Cloud Run 버전을 선택하고 적용을 클릭합니다.
여기에 모든 Cloud Run 로그가 표시됩니다. 서비스 이름이나 버전 이름으로 필터링할 수 있습니다.
심각도에서 오류를 클릭합니다.
애플리케이션에서 발생한 오류가 여기에 표시됩니다. 애플리케이션이 더 많고 서비스를 더 많이 사용한다면 이 뷰에서 오류의 다양한 소스를 구별하기가 어려울 수 있습니다.
Google Cloud 콘솔 제목 표시줄의 검색 필드에 Error Reporting을 입력하고 검색을 클릭한 후 Error Reporting을 클릭합니다.
오류는 이 페이지에 그룹화되어 있습니다. 오류는 대부분 Cloud Run의 Python 애플리케이션이 비정상 종료될 때 자동으로 생성되었습니다. 수동으로 발생시킨 오류도 표시됩니다.
1시간을 클릭합니다.
Intentionally Created Error를 클릭합니다.
유사한 오류가 여기에 그룹화됩니다. 오류를 그룹화하면 문제를 디버그하는 데 도움이 될 수 있습니다.
샘플 중 하나에서 로그 보기를 클릭합니다.
이 링크를 클릭하면 Cloud Logging의 해당 로그 항목으로 돌아갑니다. 기록된 오류를 고정하고 같은 시간대에 발생한 로그를 살펴볼 수 있습니다.
애플리케이션을 컨테이너화하고 Cloud Run에 배포했으며 발생한 문제를 디버그했습니다. 필요한 역할을 서비스 계정에 부여하고 로컬 배포와 Cloud Run 배포를 모두 지원하도록 OAuth 구성을 업데이트했습니다. 애플리케이션에 Error Reporting을 추가하고 Google Cloud Observability의 애플리케이션 개발 기능을 살펴봤습니다.
실습을 완료하면 실습 종료를 클릭합니다. Google Cloud Skills Boost에서 사용된 리소스를 자동으로 삭제하고 계정을 지웁니다.
실습 경험을 평가할 수 있습니다. 해당하는 별표 수를 선택하고 의견을 입력한 후 제출을 클릭합니다.
별점의 의미는 다음과 같습니다.
의견을 제공하고 싶지 않다면 대화상자를 닫으면 됩니다.
의견이나 제안 또는 수정할 사항이 있다면 지원 탭을 사용하세요.
Copyright 2026 Google LLC All rights reserved. Google 및 Google 로고는 Google LLC의 상표입니다. 기타 모든 회사명 및 제품명은 해당 업체의 상표일 수 있습니다.
현재 이 콘텐츠를 이용할 수 없습니다
이용할 수 있게 되면 이메일로 알려드리겠습니다.
감사합니다
이용할 수 있게 되면 이메일로 알려드리겠습니다.
한 번에 실습 1개만 가능
모든 기존 실습을 종료하고 이 실습을 시작할지 확인하세요.