Producer (producer_id) { void SendRow(row, consumer_id) : Called to send a row to a given consumer on behalf of this producer. } Consumer (consumer_id) { string ReceiveRow() : Called to receive one row for this consumer. } Controller { StartShuffle() : Called before any producers or consumers start sending or receiving rows. EndShuffle() : Called after all producers and consumers have successfully sent and received all rows. }
구글 빅쿼리에서는 비동기 처리방식인 Job을 통해서 데이터를 로딩하는 방법 외에도 실시간으로 데이터를 로딩 할 수 있는 방법으로 스트리밍(Streaming) API를 제공한다. 이 글에서는 구글 빅쿼리에서 제공하는 스트리밍 API를 이용해서 실시간으로 데이터를 로딩하는 방법을 알아보도록 하자.
스트리밍(Streaming) API
비동기 연산인 Job을 통한 데이터 로딩방식이 아닌 API형태로 tabledata().insertAll() 메소드를 제공하여 한번에 하나씩레코드를 삽입하는 방법을 제공한다. 하나의 레코드에는 하나 또는 다수의 행을 포함할 수 있다.
*레코드는 빅쿼리가 지원하는 데이터 타입으로 하나 이상, 다수의 데이터 필드에 대한 일종의 집합이다.
*스트리밍 API를 이용한 데이터 로딩은 partition table에 적용되지 않는다.
스트리밍 로딩의 할당량 정책(quota policy)
스트리밍 API를 사용한 데이터로딩은 실시간으로 처리되는 부분으로 Job의 데이터로딩(batch) 방법에 비해서 처리 가능한 데이터의 크기와 행의 수가 제한적이다.
최대 행 사이즈 : 1MB
HTTP 요청 사이즈 제한 : 10MB
초당 최대 입력 가능 행 수 : 테이블 당 100,000 행, 프로젝트 당 1,000,000 행
요청당 최대 입력 가능 행 수 : 제한은 없으나, 최대 500 행을 권장
초당 최대 바이트 크기 : 100MB
*스트리밍 데이터 로딩 시에 위의 정책을 초과하는 경우에 에러가 발생한다. 따라서 그러한 경우는 Job을 통한 데이터 로딩을 권장한다.
데이터 일관성 보장
데이터에 대한 일관성을 보장할 수 있는 옵션으로 각각의 입력 행에 대해서 insertId를 적용할 수 있다. insertId는 행 입력 시 최소1분 정도 빅쿼리가 기억하고 있게 된다.
*이미 입력된 행에 대해서 insertId를 통해 중복된 데이터는 추가로 입력되지 않으며, 만약 변경된 데이터(행)를 입력하면 해당 insertId를 가진 데이터(행)는 변경된 데이터(행)로 입력된다.
템플릿 테이블
templateSuffix 속성을 통해서 지정한 대상 테이블을 기본 템플릿으로 하여 같은 스키마를 가진 새로운 테이블을 자동으로 생성할 수 있다.
templateSuffix의 값은 사용자가 임의로 설정할 수 있다.
<대상 테이블> + <templateSuffix> 형태로 새로운 테이블이 생성된다.
Tabledata: insertAll정의
Tabledata는 API형태로 제공되는 Resource type으로 스트리밍 데이터 로딩을 지원하는 insertAll 메소드를 포함하고 있다.
HTTP 요청(request) 기본형식
POST https://www.googleapis.com/bigquery/v2/projects/projectId/datasets/datasetId/tables/tableId/insertAll
POST요청으로 각각 해당되는 project, dataset, table ID를 설정하면 된다.
*단순스트리밍 로딩을 위해서는 따로 HTTP(S)트래픽을 허용하지 않아도 위의 다른 GCP서비스에 대한 접근 범위 설정을 통해 Streaming API에 사용에 대한 권한을 가지게 된다. 때문에 무리없이 실행은 가능하다. 하지만 실제 어플리케이션 구성에서는 구성환경에 맞춰서 HTTP, HTTP(S)에 대한 트래픽을 허용해기 위해 방화벽 규칙을 설정해야 될 것이다.
VM인스턴스 접근 범위 확인하기
Access scopes에 대한 적합한 설정이 되어있어야 한다는 것만 명심하자.
또한 Access scopes는 VM을 생성 할 때만 적용 가능하다.
VM 신규 생성 시 주의사항
Identity and API access에서 적합한 Access scopes를 설정하고 생성해야 한다.
BigQuery API 활성화
스트리밍 데이터 로딩을 실행하기 위해서는 BigQuery API를 활성화 해야 한다. 다음의 BigQuery API페이지로 이동한다.
구글 빅쿼리는 npm으로 node.js Library를 제공한다. 다음의 명령어를 실행해서 Bigquery API Client Library를 설치한다.
% npm install googleapis --save
스트리밍 데이터 로딩하기
이제 스트리밍 데이터 로딩을 위한 준비는 완료되었다. Node.js와 스트리밍 API를 사용해서 데이터 로딩을 해보도록 한다.
Streaming API 기본 예제 - Node.js
vi등의 편집기를 이용해서 app.js파일을 열고 다음과 같은 내용을 추가한다.
var google = require('googleapis'); var bigquery = google.bigquery('v2');
google.auth.getApplicationDefault(function(err, authClient) { if (err) { console.log('Authentication failed because of ', err); return; } if (authClient.createScopedRequired && authClient.createScopedRequired()) { var scopes = ['https://www.googleapis.com/auth/cloud-platform']; authClient = authClient.createScoped(scopes); }
var request = { // TODO: Change placeholders below to appropriate parameter values for
the 'insertAll' method:
// Project ID of the destination table. projectId: "", // Dataset ID of the destination table. datasetId: "", // Table ID of the destination table. tableId: "", resource: {}, // Auth client auth: authClient };
resource: {} 에서 중괄호 안에 위에서 설명한 기본 Request body의 형식에 맞게 실제 입력할 데이터의 내용을 입력한다.
bigquery.tabledata.insertAll() {}부분에서 데이터 로딩이 실행되는 부분으로, 만약 에러가 있다면 에러에 대한 내용을 반환한다.
스트리밍 로딩 테스트
이제 예제 코드에 대한 대략적인 구조를 파악하였다면 스트리밍 API를 사용해서 실제 테이블에 데이터를 입력해보자.
테이블 정보
테스트에 사용할 테이블은 앞서 구글 스토리지를 활용한 데이터 로딩에서 생성한 csv_test 테이블을 사용하도록 한다. 테이블 csv_test는 다음과 같은 스키마를 가지고 있다.
Node.js 코드 작성하기
projectId: “사용자의 프로젝트ID”
datastId: “데이터를 입력할 테이블을 가지고 있는 데이터셋ID”
tableId: “실제로 데이터를 로딩 할 테이블Id”
resource: { 입력 할 데이터 }
위에서 설명한 request body의 형식으로 대상 테이블의 스키마에 대응되는 적합한 값을 입력해야 한다. 입력을 완료하고 파일을 저장한다.
데이터 로딩 실행
이제 앞서 작성한 내용의 데이터를 로딩하기 위해 다음 명령어를 실행해서 Node.js서버를 구동한다.
%npm start
해당 스트리밍 로딩 요청에 대한 tableDataInsertAllResponse로 응답이 완료됨을 확인할 수 있다. 응답이 완료된 것을 확인하고 ctrl+c를 입력하여 실행을 중지한다.
데이터 로딩 결과 확인하기
이제 빅쿼리 웹 콘솔(Web UI)로 이동해서 간단한 쿼리 실행을 통해 데이터가 정상적으로 입력되었는지 확인해보자.
쿼리 실행하기
좌측 상단의 COMPOSE QUERY 버튼을 클릭한다.
다음과 같이 쿼리를 입력하고 RUN QUERY 버튼을 클릭하여 쿼리를 실행한다.
SELECT word, word_count, corpus, corpus_date
FROM load_test.csv_test
WHERE word_count=1111
쿼리가 실행되었다. 앞서 입력한 데이터를 확인 할 수 있다.
템플릿 테이블을 이용한 테이블 자동생성
이제 앞서 설명한 templateSuffix속성을 활용해 csv_test 테이블을 템플릿으로 하여 같은 스키마를 가진 새로운 테이블을 생성해보자.
Node.js 코드 작성하기
vi편집기등으로 app.js파일을 열고 다음의 내용을 추가하고 파일을 저장한다.
templateSuffix: "String형의 임의의 값"
자동 테이블 생성 및 데이터 로딩 실행
템플릿 테이블을 활용해서 자동으로 새로운 테이블 생성 및 데이터로딩을 위해 node.js 서버를 실행한다.
%npm start
응답이 완료되었다. ctrl+c를 입력하여 실행을 중지한다.
자동 테이블 생성 및 데이터 로딩 결과 확인하기
이제 다시 빅쿼리 웹 콘솔로 이동해서 테이블이 자동으로 생성되고 입력한 데이터가 제대로 로딩되었는지 확인한다. (새로고침이 필요할 수 있다.)
먼저 자동 생성된 테이블 부터 확인한다. 앞서 설명한 것처럼 <대상 테이블> + <templateSuffix>의 형태로 csv_test1234라는 새로운 테이블이 생성되었다. 템플릿의 대상이 되는 테이블인 csv_test와 동일한 스키마를 가진다.
데이터 로딩 결과 확인하기 - 자동생성 테이블
이제 자동으로 생성된 테이블을 확인하였다면 해당 테이블에 스트리밍으로 입력한 데이터를 확인해보도록한다.
쿼리 실행하기
COMPOSE QURERY버튼을 클릭해서 다음과 같은 쿼리를 입력하고 RUN QUERY 버튼을 클릭하여 쿼리를 실행한다.
SELECT word, word_count, corpus, corpus_date
FROM load_test.csv_test1234
WHERE word_count=1111
쿼리가 실행되었다. 앞서 입력한 데이터를 확인 할 수 있다.
*날짜 단위 또는 각각의 사용자 단위 등으로 테이블을 분할하여 생성할 필요가 있을 때,
templateSuffix의 값에 따라서 자동으로 테이블을 생성하여 데이터를 입력할 수 있기 때문에 매우 유용한 기능이다.
자동 테이블 생성 참고사항
templateSuffix속성을 활용해서 자동으로 테이블 생성하고 데이터를 입력한 경우에 빅쿼리
웹콘솔에서 바로 Preview를 클릭하면 스트리밍 버퍼에서 데이터 로딩을 통해 입력한 데이터를
가지고 있어서 입력한 값이 바로 나타나지 않을 수 있다.
*스트리밍 데이터 입력에 수초가 소요될 수 있으며, 입력된 데이터를 복사하고,
내보내기에 사용 될 수 있기까지 90분까지 소요 될 수 있다
데이터 일관성 확인
앞서 insertId를 통해 데이터의 일관성을 보장해주는 부분에 설명하였다. 이제 실제로 insertId를 사용해 데이터가 어떻게 변화하는지 확인해본다.
Node.js 코드 작성하기
vi등의 편집기를 이용해서 app.js파일을 열고 다음의 내용을 추가하고, 입력할 데이터의 내용을 수정한다.
insertId: "String형의 임의의 값"
입력 데이터의 경우 앞서 테스트한 결과와 구분을 위해 다른 값으로 변경한다.
데이터 로딩 실행 - insertId
insertId가 적용된 데이터로딩을 하기 위해서 node.js서버를 실행한다.
%npm start
응답이 완료되었으면 빅쿼리 웹 콘솔로 이동해서 입력된 데이터를 확인한다.
데이터 로딩 결과 확인하기 - insertId
빅쿼리 웹 콘솔에서 COMPOSE QUERY를 클릭하고 다음의 쿼리를 입력한다.
SELECT word, word_count, corpus, corpus_date
FROM load_test.csv_test1234
WHERE word_count=2222
RUN QUERY를 클릭하여 쿼리를 실행하고 입력된 데이터를 확인한다.
쿼리 수행결과를 통해, 정상적으로 입력된 데이터를 확인 할 수 있다.
데이터 중복 입력 확인하기
다시 SSH터미널에서 ctrl+c를 입력하여 서버 실행을 중지하고 app.js의 내용을 변경하지 않고, 다시 한번 node.js서버를 실행한다.
데이터 중복 확인 - 쿼리 테스트
빅쿼리 웹 콘솔로 이동해서 위와 동일한 쿼리를 실행해서 결과를 확인한다.
쿼리를 실행하면 앞서 입력한 데이터(행)만 나타난다. 같은 insertId를 가지고 있기 때문에 중복된 데이터가 추가로 입력되지 않는다.
*insertId가 없는 경우, 스트리밍 로딩을 할 때 데이터의 중복에 관계없이 새로운 데이터(행)가 추가된다. 각각 테스트해보길 권장한다.
데이터 변경하기 - Node.js 코드 수정하기
SSH 터미널에서 node.js서버를 중지하고 vi등의 편집기로 app.js파일을 열고 데이터의 내용을 변경하고 저장한다.
데이터 변경 후 로딩 실행 - insertId
앞서 같은 insertId를 가진 상태에서 변경한 데이터를 로딩하기 위해 다음 명령어를 실행해서 node.js서버를 구동한다.
%npm start
응답을 확인하고 웹 콘솔로 이동해서 입력된 데이터를 확인해보자.
데이터 변경 입력 후, 로딩 결과 확인하기
기존에 데이터가 어떻게 변화하였는 지 확인하기 위해 빅쿼리 웹 콘솔에서 앞서 실행한 쿼리를 입력하고 결과를 확인한다.
SELECT word, word_count, corpus, corpus_date
FROM load_test.csv_test1234
WHERE word_count=2222
앞서 위의 쿼리 실행을 통해 데이터가 로딩된 결과를 확인했었다. 하지만 해당 쿼리가
실행되면 조회되는 데이터가 없음을 확인 할 수 있다
이번에는변경한데이터의 word_count값인 3333으로 WHERE 조건을변경하고쿼리를실행해보자
SELECT word, word_count, corpus, corpus_date
FROM load_test.csv_test1234
WHERE word_count=3333
변경해서 입력한 데이터에 대한 조회결과가 나타난다. 이와 같이 같은 행에 대한 insertId가 적용된 상태에서 데이터가 변경되어 다시 입력되는 경우, 기존의 입력된 데이터는 변경된다.
*insertId의 경우 데이터의 일관성을 확인하고 보장하기 위해 좋은 수단이 될 수 있으나, 앞서 언급한 것처럼 1분정도만 보장되는 시간적인 제약이 있으니 참고하기 바란다.
결론
빅쿼리의 스트리밍 데이터 로딩의 경우, 몇가지 제약적인 부분은 있지만, 실시간으로 대량의 이벤트 로그 분석, 실시간으로 데이터와 연동하는 dashboard등에 활용하기 좋다. 또한 빅쿼리의 대용량의 데이터 분석 뿐만 아니라 실시간의 데이터 로딩, 분석을 융합적으로 활용하면, 급변하는 시장에서 빠르게 대응 할 수 있는 또 하나의 대안이나 수단으로 이용할 수 있을 것이다.
구글의 대용량 데이터 분석 서비스인 빅쿼리에 구글 클라우드 스토리지를 활용하여 CSV, JSON형식의 데이터를 로드하고 테이블을 생성하는 방법에 대해서 알아보도록 한다.
또한,빅쿼리에서는 데이터 파일의 단일 업로드뿐만 아니라 병렬 업로드(다중파일 동시 업로드)도 제공한다.따라서, 이번 글의 뒤쪽에서는 단일CSV파일로 데이터로딩을 해보고, 그 CSV파일을 여러 개의 파일로 분할하여 병렬로 데이터를 로드해서 각각의 처리 속도를 확인해본다.
그리고 CSV 병렬 업로드를 위해 분할한 데이터를 이용하여 JSON, Avro포맷으로 변환하여 각각의 형식에 따라 동일데이터라도 데이터 로딩시간이 어떻게 달라지는지 확인해보도록 하자
구글 클라우드 스토리지(Google Cloud Storage : GCS)
구글 클라우드 스토리지는 구글 클라우드 플랫폼에서 지원하는 BLOB(Binary large object) Store로 구글 클라우드 플랫폼의 모든 서비스들과 연계하여 사용이 가능하다.구글 클라우드 플랫폼에서 제공하는 파일,미디어 등의 저장에 특화된 서비스이다.
GCS 스토리지 클래스
Standard:
높은 data availability(99.9%)와low latency을 가지고 있어서 데이터에 대한 빠른 응답속도(ms)를 보인다.따라서 데이터에 대한 빠른 접근,빈번한 접근이 필요한 경우에 사용하기 적합하다.활용하기 적합한 예로는 웹사이트 컨텐츠,모바일 또는 게임 어플리케이션, 등이 있다.
Durable Reduced Availability (DRA) :
Standard에 비해 약간 낮은 가격과 data availability(99%)를 가지고 있다.
데이터 백업,배치(batch) 작업에 사용하기 적합한 클래스이다.
Nearline : data archiving 이나 online backup, 재해복구(disaster recovery)용도로 사용하기 적합한 클래스로 가장 저렴한 비용으로 이용할 수 있다. 데이터 접근에 시간단위가 소요되는AWS의 glacier서비스등에 비해서 매우 빠른 속도로 초 단위(대략3초)로 다른 클라우드 업체들의 유사서비스들에 비해서 매우 높은 성능을 가진다.
*구글 클라우드 스토리지 클래스 모두 동일한 API를 사용하고 AWS의 S3와 API호환되서 API사용에 대한 부담이 적다.
GCS 기본 구성요소
프로젝트(Project) :
최상위 컨테이너로 구글 클라우드 스토리지의 모든 자원(resources)은 프로젝트 위에서 생성되고 관리된다. 또한 스토리지 자원들에 대하여 권한제어가 가능하다.
버켓(Bucket) :
데이터 또는 파일을 저장하고 관리하기 위한 컨테이너이다.구글 클라우드 스토리지에서의 최소단위인 Object(각각의 데이터 또는 파일단위)가 저장되는 공간이며, 버켓 생성 시에 앞서 설명한 클래스와 데이터가 저장될 위치를 지정하여야 하고 생성 후에는 변경이 불가능하다.새로 생성하거나 다른 버켓으로 이동시키는 등의 방법을 사용하여야 한다.
오브젝트(Object) :
실제로 구글 클라우드 스토리지에 저장되는 각각의 데이터 또는 파일을 의미한다. 하나의 오브젝트는 최대 5TB까지 저장할 수 있다.
빅쿼리 기본구조
*빅쿼리에 대한 개념, 아키텍쳐 등의 기본적인 이해가 필요하다면 아래 주소의 정보를 참고하기 바란다.
JSON포맷의 데이터를 로드하고 테이블을 생성하기 위해 내용을 입력하고 필요한 옵션을 설정하여 테이블을 생성한다. .
Source Data
Location : gs://load-bigquery/shakespeare.json
JSON 파일도 마찬가지로 구글 클라우드 스토리지의 JSON파일 URI를 입력한다
File format : JSON(Newline Delimited)
Destination Table
Table name : json_test(임의의 값)
Schema
Edit as Text에 다음과 같이 텍스트로 JSON형태의 스키마를 입력한다.
[
{
"name": "word",
"type": "STRING",
"mode": "REQUIRED"
},
{
"name": "word_count",
"type": "INTEGER",
"mode": "REQUIRED"
},
{
"name": "corpus",
"type": "STRING",
"mode": "REQUIRED"
},
{
"name": "corpus_date",
"type": "INTEGER",
"mode": "REQUIRED"
}
]
*Add Field로 각각 생성해도 상관없다.각각의 환경에 따라서 사용하기 편한 방식으로 이용하도록 하자.
다음과 같이 스키마 정보가 정상적으로 입력된 것을 확인 할 수 있다.
이제 나머지 값은 기본값으로 하여 Create Table 버튼을 클릭하여 테이블을 생성해보자.
JSON포맷의 데이터로 생성한 테이블이 생성되었다.
테이블 테스트 – JSON
COMPOSE QUERY를 클릭하여 CSV로 입력한 데이터와 같은 데이터를 가지고 있기 때문에, 앞에서 CSV를 테스트한 쿼리를 이용하여 테스트해보자.
SELECT word, word_count, corpus, corpus_date
FROM load_test.json_test
ORDER BY word_count DESC LIMIT 10
RUN QUERY버튼을 클릭하여 쿼리를 실행해보자
테스트로 입력한 쿼리가 정상적으로 실행되었다.
*구글 클라우드 스토리지를 이용하여 데이터 교환의 표준 포맷이라고 할 수 있는 CSV, JSON형식의 데이터를 이용해 테이블을 생성하고 데이터를 로드하였다. 위의 예제에서는 데이터를 로딩하는 방법에 대한 설명하기 위해 작은 용량의 데이터를 가지고 진행하였다.하지만 빅쿼리는 기본적으로 대용량의 데이터를 실시간에 가까운 속도로 처리하고 분석하기 위해 설계되었고,GB,TB급의 데이터라도 매우 빠른 속도로 로딩이 가능하다. 따라서 위의 예제의 데이터보다는 비교적 큰 데이터를 이용해 앞서 언급한 단일, 병렬, 포맷에 따른 데이터 로딩시간을 확인해보도록 한다
업로드 속도 비교하기
시작하기전에 먼저 각각의 방식에서 속도(성능)를 확인하는 것이 주요 목적으로
각각의 업로드 방법에 대한상세한 설명은 생략한다.
기본 준비사항
원본 데이터
아래는 원본 테이블의 정보이다. 2014년의 항공편에 대한 데이터를 가지고 있으며 용량은 1GB가 약간 넘으며, 6,303,310개의 행(Rows)으로 이루어져 있다.
bq 명령어 도구
앞서 언급한 Command-line interface로 제공되는 도구이다. 파이썬 기반의 도구로 Google Cloud SDK에 포함되어 있으며, 기타 SSH를 사용하는 경우 따로 설치도 가능하다. 이후 진행 할 단일/병렬 업로드에 bq도구를 활용하도록 하겠다.
VM인스턴스 준비
테스트를 위해 Google Compute Engine의 VM인스턴스를 하나 생성하거나 기존의 VM인스턴스를 사용한다.
테스트에 사용한 VM은
machine type : n1-standard-1 (1 vCPU, 3.75 GB memory)
마지막으로 JSON과 동일한 방법으로 CSV병렬 업로드에 사용한 6개의 파일을 Avro포맷으로 변환하여 병렬 업로드를 하여 속도를 확인해보자. 변환과정은 생략한다.
데이터 준비
CSV -> Avro으로 변환한 파일을 구글 클라우드 스토리지에 저장한다.
같은 데이터를 가지고 있지만 CSV, JSON포맷과 비교했을 때데이터 파일의 크기가 작다.
다음 명령어를 통해 Avro포맷의 병렬 업로드를 실행한다.
bq load --source_format=AVRO \
bigquery-1369:load_test.flight_avro_Multi \
gs://load-bigquery/avro/flight*.avro
--source_format=AVRO : Avro포맷으로 지정한다
Avro의 경우 데이터파일에서 스키마의 정보를 포함하고 있기에 스키마를 따로 지정하지 않아도 된다.
테이블이 생성 되었다
웹 콘솔의 job History를 통해 데이터 로딩에 소요된 시간을 확인해보자.
Avro포맷의병렬 데이터 로딩에 40초가 소요된 걸 확인할 수 있다.
(여러 번 테스트 해본 결과 35 ~ 45초 정도 소요됨)
*여러 번 테스트 한 결과 CSV 병렬 업로드 보다 빠르고 JSON보다는 느리다.
데이터 로딩 결과(시간)
CSV(단일)
CSV(다중)
JSON(다중)
Avro(다중)
업로드 시간
40초 ~ 60초
36초 ~ 50초
20초 ~ 30초
35 ~ 45초
결론
빅쿼리가 지원하는 데이터 포맷(CSV,JSON, Avro)을 이용해동일한 데이터에 대해서단일 파일 데이터 로딩을 포함하여, 단일 데이터파일을 분할하여 여러 개로 나눠서 병렬(다중파일 동시 업로드)데이터 로딩을 테스트하였다.다음과 같은 결과를 확인할 수 있었다.
로딩 속도는 CSV > Avro > JSON
데이터의 크기(비용적인 측면)는 Avro < CSV < JSON
물론 데이터의 크기가 더 커진다면 결과가 달라 질 수도 있겠지만, 위에서 테스트한 정보를 토대로 이야기하면 1GB의 용량에 6백만 행을 가진 데이터가 작지 않은 데이터라고 볼 수 있으나, 현재와 같이 빅데이터가 일반화 되어가는 시기에 수십,수백GB에서 TB까지(또는 그 이상)의데이터의 로딩의 여러가지 측면(비용,속도)을 생각하면, Avro포맷을 고려해 보는 것도 좋은 선택이 될 수 있을 것이다.
맞춤설정(custom)모드는 사용자가 직접 IP범위(10.0.0.0/8 또는 192.168.0.0/16이내)를 지정하여 서브넷을 구성할 수 있다.
레거시(Legacy) 모드 : non-subnetwork
구글 클라우드 안에서 서브넷없이 단일 IP범위로 단일 게이트웨이로 구성되는 네트워크로 모든 리전범위에 걸쳐서 사용 할 수 있다. IP주소는 전체범위로 생성되기 때문에 리전이나 존범위에서 연속적이지 않을 수 있다.
*레거시 모드의 경우 클라우드 콘솔(Web UI)로 생성 할 수 없으며, CLI 툴(Cloud SDK, SSH등)을 사용해서 gcloud명령어를 통해서 만 생성 가능하다.
네트워크 참고사항
* Default네트워크는 자동(auto)모드로 생성되는 네트워크이다.
* 네트워크는 프로젝트당 5개까지 구성할 수 있다.
* 프로젝트당 최대 100개까지 서브넷 생성이 가능하다.
*각각의 네트워크들은 상호 변경이 불가능하며, VM인스턴스 또한 처음 생성할 때에 지정한 네트워크(Internal IP)의 경우 변경이 불가능하다.
NAT(Network Address Translation) Gateway
사설IP를 공인IP로 변환하여 주는 통신망의 통신 변환기이다. NAT을 사용하는 목적은 다수의 사설IP를 하나의 공인IP로 변환하여 다수의 사설IP가 하나의 공인IP를 사용할 수 있도록 함으로써 한정자원인 공인IP를 절약하는 효과가 있다. 또한 공개된 인터넷에 사설IP의 외부노출 및 직접연결을 차단하고 방화벽을 설치하여 외부공격으로부터 사용자의 통신망을 보호하는 기본적인 수단으로 활용 할 수 있다.
IP주소
Internal IP(내부/사설 IP) :
모든 VM은 생성 시 내부 IP를 가진다. 적용되는 IP는 위에서 설명한 서브넷(auto or custom)또는 레거시(legacy)로 지정한 IP범위를 가지게 되고 같은 네트워크 상에서는 VM인스턴스의 이름을 기반으로 내부 VM들과 통신을 한다. 외부 인터넷과의 통신이 제한된다.
External IP(외부/공인 IP) :
내/외부(인터넷) 통신이 가능하며, 임시(ephemeral), 고정(static), 없음(none)으로 생성 가능하다. 구글 클라우드에서 같은 네트워크가 아니더라도 VM인스턴스들은 외부IP를 통해 통신하게 되며 외부IP로 통신하더라도 구글 내부망을 이용하기 때문에 속도, 보안, 비용적인 측면에서 이점을 가진다.
Routes(경로)
네트워크에서 효율적인 통신을 위해서 수많은 네트워크들 중 최적의 경로를 결정하는 역할이 필요하다. 이때 필요한 것들 중의 하나가 Route이다. 이러한 Route들이 모여서 Routing Table(라우팅 테이블)이 된다.
구글 클라우드에서의 Routes란 일종의 라우팅 테이블이며 전체 글로벌 범위에서 사용 가능하다. 네트워크 생성 시 인터넷 게이트웨이와 내부 네트워크에 대한 경로는 기본적으로 생성되며, 추가적인 경로 설정을 통해 다대일(many-to-one) NAT(Network Address Translation) Gateway, VPN(Virtual Private network) Gateway 구성 등에 사용할 수 있다.
방화벽 규칙(Firewall-rules)
구글 클라우드 네트워크로 들어오는 모든 Inbound 트래픽에 대해서 막혀 있으며, 인바운드 허용(Inbound Allow)규칙만 생성 할 수 있다.
default네트워크에서 TCP 22번포트(SSH), 3389(RDP), icmp, Internal(VM간의 통신)을 제외하고 모두 막혀 있다(= 직접 서브넷이나 레거시로 구성하여 내트워크를 생성하는 경우에 방화벽 규칙이 없다.)
CIDR표기법과 VM인스턴스 태그를 사용한 범위로 트래픽을 제한 할 수 있다.
네트워크 로드밸런싱(TCP/UDP 기반)
TCP 로드밸런서는 HTTP 로드밸런서와는 다르게 리전 단위로만 사용이 가능하다. (리전간의 밸런싱은 HTTP 로드밸런서만 가능하다.) 리전 범위에서 서버의 부하를 분산하고 장애를 인지하여 밸런싱 하는L4스위치와 비슷한 기능을 가진다.
또한 pre-warming이 필요 없어서 구성 후 바로 사용 가능하다.(몇몇 클라우드 로드밸런서의 경우 갑자기 높은 부하를 주면 받아내지 못하는 경우가 있어서 미리 그만한 부하를 지속적으로 줘서 로드밸런서의 크기를 키워주는 pre-warming이 작업이 필요하다)
프로토콜 전달(protocol forwarding)을 사용하기 위해서 전달규칙(Forwarding rule)에서 지정한 IP를 통해 요청이 들어오면 해당 요청에 대해서 처리할 수 있게 지정한 인스턴스 또는 인스턴스 풀에 전달하여 요청을 처리한다. 추가적인 옵션으로 Health check를 구성하여 주기적으로 인스턴스의 상태를 체크하고 상태가 안좋은 인스턴스의 경우 제외하는 기능을 한다.
리전과 존(Region / Zone)
리전은 지리적인 위치인 대륙 범위로 생각하면 될 것이다.
현재 미국 동부, 중앙과 유럽 서부와 아시아 동부 리전이 있다. 존은 각각의 리전(지역)에 실제로 위치한 데이터 센터이다.
기본적으로 구성될 구성요소들과 용어들에 대한 간단한 소개를 하였으며 이제 서브넷과 TCP로드 밸런싱을 이용해 간단한 웹 어플리케이션을 구성해보고, 추가적으로 NAT gateway구성을 해보도록 하자.
네트워크 및 서버 구성하기
구글 클라우드 가입하기
먼저 https://cloud.google.com/ 에 접속해서 Try It Free버튼을 클릭하여 로그인을 한 후, 해당되는 내용들을 입력하여 구글 클라우드 서비스에 가입을 한다.(신용카드 정보 입력 필요)
계정이 생성되면 자동으로 $300한도로 60일동안 사용할 수 있는 무료 평가판으로 이용 가능하다. ($300을 먼저 소모하거나 60일이 경과하면 소멸한다.)
신용 카드정보를 입력하지만 확인 용도이며, 사용자가 직접 업그레이드를 하지 않는 이상 비용이 결제 되지 않는다.
프로젝트 생성
구글 클라우드는 VM을 포함한 모든 서비스 자원들을 묶은 하나의 컨테이너 형태로 프로젝트라는 개념을 사용한다. 처음 무료 평가판을 등록하면 프로젝트가 없으니 새로 생성하여야 한다.
네트워크 생성하기
좌측 상단의 탭을 선택하고 COMPUTE부분에서 하단의 Networking을 선택하여 네트워크 메뉴로 이동한다.
상단의 CREATE NETWORK메뉴를 선택하고 네트워크를 생성한다.
Name : sub-nw
Subnetworks -> custom : Name : sub-asia
Region : asia-east1
IP address range : 192.168.10.0/24
이번 예제는 네트워크 이름 sub-nw(임의의 값)
Subnetworks에서 Custom을 선택하고 서브넷의 이름은 sub-asia(임의의 값)
Region(지역)은 asia-east1을 선택하고 범위는 192.168.10.0/24(지정가능한 범위<10.0.0.0/8 또는 192.168.0.0/16이내>에서 임의의 범위) 로 지정하였다.
아래와 같이 네트워크가 생성되었다.
간단하게 프로젝트내부의 네트워크 정보를 확인 할 수 있으며 해당 이름을 클릭하면 자세한 정보를 얻을 수 있다.
방화벽규칙(Firewall-rules) 생성
좌측메뉴에서 Firewall rules를 선택하면 방화벽 규칙들에 대한 정보를 얻을 수 있으며 관리를 할 수 있다. 위에 설명한대로 default네트워크를 제외하고는 내부통신을 위한 TCP, UDP, ICMP까지 모두 수동으로 생성해야 한다.
방화벽 이름은 asia-sub-internal 으로 Network는 이전에 생성한 sub-nw 를 선택하고
Source filter는 Subnetworks를 지정해서 이전에 생성한 sub-asia를 선택한다.
Source filter의 경우 위에 설명한 CIDR범위나 인스턴스 태그를 지정하여 허용하게 할 수 있다. 또한 하단의 Target tags는 인스턴스 태그만 지정 가능하며, 지정하지 않을 경우 해당 네트워크의 모든 인스턴스에 적용된다.
Allowed protocols and ports는 같은 네트워크안에서 VM들의 통신을 위해 tcp;udp;icmp 를 입력하여 생성한다.
추가로 SSH접속을 위한 TCP 22번 포트 방화벽 생성
Name : asia-sub-ssh
Network : sub-nw
Source filter : Allow form any source (0.0.0.0/0)
Allowed protocols and ports : tcp:22
TCP 22번 포트의 경우 외부에서 SSH 접속을 위한 용도 때문에 0.0.0.0/0(모든 범위)로 생성한다.
프로젝트 환경에 맞게 지정하길 바라며 이 예제에서는 모든 범위로 지정한다.
VM 인스턴스 생성
좌측 상단 탭을 클릭하여 Compute Engine탭으로 이동한다.
상단의 CREATE INSTANCE를 클릭하여 VM을 생성한다.
이 예제에서는 다음과 같이 구성한다.(각자 원하는 환경으로 Machine type, Zone등은 편하게 구성해도 무방하며 리눅스 기반의 OS로 설명한다)
VM인스턴스 이름 : nat-node-as-1
Zone : asia-east1-a
Machine type: 1vCPU, 3.75 – n1-standard-1
Boot disk는 Change클릭하여 Ubuntu 14.04 LTS / SSD 10GB
Identity and API access는 default access로도 충분하지만 Full access선택 (구글 클라우드 서비스들에 대한 VM의 액세스 범위를 지정하는 부분이다. 생성 후 에는 추후에 변경이 불가능하니 신중하게 선택해야 한다.)
하단의 Management, disk, networking, SSH keys를 클릭하여 첫번째 Management탭에서 Tags를 nat-as 세번째 Networking탭에서 network는 위에서 생성한 sub-nw를 선택하고
Subnetwork는 역시 위에서 생성한 sub-asia 을 선택한다
Internal IP(내부IP)는 Automatic(자동)또는 Custom(맞춤설정)으로 직접 이전에 생성한 범위에 맞춰서 생성한 범위로 지정 가능하나, 이 예제에서는 자동으로 생성하겠다. (위에서 생성한 아시아 리전의 서브넷인 sub-asia범위로 지정한 192.168.10.0/24범위에서 자동 생성된다.)
External(외부IP)는 Ephemeral(임시)로 생성한다. 이후 NAT구성시 none(없음)으로 변경 예정이다.
나머지 값은 기본값으로 적용하여 생성한다.
두번째 VM인스턴스 생성
위에서 생성한 인스턴스 nat-node-as-1이 생성되면 이름을 클릭하고 상세페이지로 들어가서 상단의 CLONE를 클릭한다.
모든 값이 동일한지 확인하고 만약 다르다면 위에서 설정한 값과 동일하게 설정하고 인스턴스 이름을
nat-node-as-2 , Zone을 asia-east1-b로 선택하여 추가로 인스턴스를 생성한다.
기존의 구성이 완료된 인스턴스를 복제하는 방법
먼저 복제할 인스턴스의 디스크를 이용해 Snapshots(복제본)을 만든다.
CREATE SNAPSHOT을 클릭하여 스냅샷을 생성한다.
Name : node-ex-my-disk
Source disk : nat-node-as-1
나머지 : 기본값
스냅샷의 이름(임의의 값)을 입력하고 source disk를 선택(기본적으로 인스턴스 들의 이름과 동일하게 생성되어 있음)하여 생성한다.
그 다음 Disks 탭으로 이동하여
CREATE DISK를 클릭하여 DISK를 생성한다.
Name : node-ex-my-disk
Zone : asia-east1-a
Source type : Snapshot
Source snapshot : node-ex-my
Size : 10GB (스냅샷과 동일하게 또는 더 크게)
나머지 : 기본값
디스크의 이름(임의의 값)을 입력하고 해당 DISK를 위치 시킬 Zone를 선택한다.
DISK의 경우 Zone범위의 리소스이다.
디스크 타입을 원하는 대로 선택하고 source type에서 중간의 Snapshot를 선택한다.
Source snapshot에서 앞서 생성한 스냅샷(모든 설치, 구성이 완료된 VM디스크의 스냅샷)을 선택하고 디스크 크기는 기존의 크기와 같게 또는 더 크게 생성한다.
스냅샷을 이용해서 디스크를 생성하고 Images탭으로 이동해서 해당 디스크에 대한 이미지를 생성한다. 이미지란 OS를 포함한 DISK를 말하며 해당 사이즈는 최소 크기이다.
상단의 CREATE IMAGE를 선택하여 이미지를 생성한다
Name : node-ex-my-ubunt
Source : Disk
Source disk : node-ex-my-disk (스냅샷을 통해 새로 생성한 디스크)
이미지의 이름(임의의 값)을 입력하고 소스를 DISK로 지정하고 Source disk는 앞서 스냅샷으로 생성한 디스크를 선택하여 생성을 완료한다
생성이 완료되면 VM인스턴스 생성 시 이미지(OS) 선택 부분에서 Your image탭에서 임의로 생성한 이미지를 통해 기존 VM인스턴스의 디스크를 복제한 이미지로 생성이 가능하다.
이 예제에서는 node.js와 MySQL을 이용해 간단한 웹 어플리케이션을 구성할 예정이다. node.js 및 MySQL설치 및 구성에 대한 자세한 설명은 생략한다.
프로그램의 기본적인 설치 후 npm express로 웹 프로젝트를 생성하고 MySQL에 입력한 값을 select query를 통해 읽어서 화면에 출력하는 웹 어플리케이션이다
VM인스턴스 페이지에서 해당 VM의 오른쪽에 있는 SSH 버튼을 클릭하여 터미널에 접속하여 프로그램들을 설치하고 구성한다.
웹 브라우저 접근을 위한 http(80포트) 방화벽 규칙을 추가한다.
Name : asia-sub-http
Network : sub-nw
Source filter : Allow form any source (0.0.0.0/0)
Allowed protocols and ports : tcp:80
먼저 앞서 생성한 VM의 내/외부 IP정보를 확인하자.
다음은 간단하게 node.js express 모듈로 웹 프로젝트를 만들고 MySQL서버에서 사전에 입력한 테이블 데이터를 가져오는 웹 어플리케이션이다.
어플리케이션이나 데이터 값이 적기 때문에 nat-node-as-1에 MySQL을 설치하고 테이블을 구성하고 값을 입력하였으며, nat-node-as-2에서는 nat-node-as-1의 MySQL DB정보를 참조하여 데이터를 읽는다.
MySQL 접속 정보이다. 인스턴스 nat-node-as-1은 자신의 DB를 사용하기 때문에 localhost로 접근하고
인스턴스 nat-node-as-2은 nat-node-as-1과 내부통신을 통해서 nat-node-as-1의 MySQL에 접근하기 위해 접속할 호스트를 nat-node-as-1의 내부IP정보(192.168.10.2)로 설정한다.
해당 웹 어플리케이션을 구동한 모습
이제 서로 다른 IP로 구성된 VM인스턴스들을 네트워크 로드밸런싱을 적용하여 하나의 IP를 사용하여 접근 할 수 있도록 하겠다.
네트워크 로드밸런싱 구성하기
좌측상단 탭을 이용해 네트워킹메뉴로 이동하여 좌측 중간의 로드 밸런싱 메뉴를 선택한다.
Create load balancer 버튼을 클릭하여 나온 3가지 메뉴 중 TCP Load Balancing에서 Start configuration을 클릭한다.
이름은 임의로 web-target을 입력하고
Name : web-target
Backend configuration
Region : asia-east-1
Backends : Select existing instances -> add an instance
: nat-node-as-1,nat-node-as-2
리전을 asia-east1을 선택하고Backends에서 기존 인스턴스를 클릭하고 Add an instance를 통해 앞서 생성한 nat-node-as-1, 2를 추가한다.
나머지 값은 기본값으로 하고 설정한다.
*Backup pool은 사전에 백업해서 구성 인스턴스 풀을 이용하여 헬스체크를 하여 장애조치를 하는 옵션이고,
Health check는 백엔드에 구성된 인스턴스의 상태를 체크하여 상태가 나쁜 인스턴스를 제외하는 기능이며,
Session affinity는 설정 옵션에 따라서 요청에 대한 처리를 지정해서 할 수 있게 하는 기능이다.
Frontend configuration으로 이동한다. IP의 경우 새로 고정IP를 생성하여 진행하며 포트는 80으로 설정한다.
임의로 IP 이름이 lb-ip인 고정 IP를 생성하고 선택한다.
IP : 104.155.228.179(lb-ip)
Port : 80
이제 기본적인 설정은 끝났으며 TCP로드밸런서를 생성한다.
Health check 생략하여 경고가 나온다. 해당 옵션은 추가가 가능하며 로드밸런서 설정이 이 가이드에서 설명하고자하는 주요내용이 아니기 때문에 이 예제에서는 생략하고 진행한다.
nat-node-as-1, 2 인스턴스에서 어플리케이션을 실행하고 로드밸런서의 동작을 테스트해보자. 프론트로 설정한 IP인 104.155.228.179로 접근 하면 다음과 같이 정상적으로 동작됨을 확인 할 수 있다.
VM인스턴스 페이지로 이동하면 앞서 생성한 VM들이 앞서 구성한TCP 로드밸런서인 web-target에 사용되고 있음을 확인할 수 있다.
기본적인 TCP네트워크 로드밸런싱을 적용하여 웹 어플리케이션 서버와 네트워크 구성을 완성하였다.
TCP네트워크 로드밸런싱을 적용한 네트워크 및 VM구성도
NAT를 이용하기
이제 로드밸런싱을 통해 고정IP로 접속이 가능하기 때문에 해당 VM들의 외부IP를
제거하여 외부인터넷과의 직접 연결을 차단하여 보안성을 향상 시킬 수 있다.
앞서 설명한 것처럼 내부IP만으로는 인터넷에 접근이 안되기 때문에 이후 인터넷에
연결이 필요한 경우(추가적인 프로그램설치, 등) 에 제한이 생긴다. 따라서
현재의 보안성을 유지하고 외부 인터넷에 접근할 수 있게 하기 위해서 NAT gateway를 구성해보자.
외부(External IP제거)
이제 로드밸런싱을 통해 고정IP로 접속이 가능하기 때문에 해당 VM들의 외부IP를 없애고 인터넷과의 직접 연결을 차단하여 보안성을 높여보자
VM인스턴스의 이름을 클릭하여 상세페이지로 이동하여 상단의 EDIT를 클릭한다.
External IP부분이 선택할 수 있게 변경되며 None를 선택하고 저장한다..
nat-node-as-2도 같은 방식으로 외부IP를 제거한다.
아래 이미지는 외부 IP를 제거한 모습이다.
NAT Gateway 역할의 VM생성
VM 인스턴스 명은 nat-gw-as(임의의 값)으로 하고 나머지부분은 전체적으로 앞서 생성한 VM(어플리케이션 서버)들의 설정을 따라 구성한다.
다르게 구성할 부분은 태그는 생략해도 되고, 하단의 추가 옵션부분에서 IP forwarding를 On으로 지정 하여야 한다. (해당부분을 제외하고 임의로 구성하여 생성할 수 있음)
*IP forwarding의 경우 최초 VM생성 시에만 적용 할 수 있다.
*일관된 기능을 위해 외부IP는 고정IP로 생성하는 게 권장되나 FREE TRIAL의 경우 리전 당 하나의 고정IP만 생성 가능하다.
앞서 설정한 로드밸런서 생성 시에 해당 리전에서 고정 IP를 사용하였기에 임시IP로 생성한다.
Route 생성
앞서 설명한 것처럼, Route(경로)란 네트워크에서 통신을 위해서 필요한 경로이다. 이러한 경로에 여러가지 옵션을 적용하여 외부 인터넷과의 연결이 가능하게 할 수 있게 해주는 NAT gateway에 필요한 설정을 할 수 있다.
여기에서는 어플리케이션 역할을 하는 nat-node-as-1, 2에서 외부 인터넷으로 트래픽을 내부통신을 통해서 NAT gateway역할을 하는 nat-gw-as로 전달하고 전달받은 트래픽 요청을 nat-gw-as의 외부IP로 외부 인터넷에 접근하는 방식을 적용한다.
네트워크 메뉴로 이동해 Routes탭으로 이동한다.
CREATE ROUTE버튼을 클릭하여 route를 생성한다
Name : nat-route
Network : sub-nw
Destionation IP range : 0.0.0.0/0
Priority : 800
Instance tags : nat-as
Next hop : Specify an instance
Next hop instance : nat-gw-as
route 이름은 nat-route(임의의 값)으로 입력하고 Network는 해당 네트워크인 sub-nw를 선택한다.
Destination IP range는 0.0.0.0/0 (전체 인터넷에 접속하기 위해 제한을 두지 않음) 으로 지정하고
Priority(우선순위) 는 800 (기본적으로 자동 생성된 route의 경우 1000)
Instance tags(인스턴스 태그)는 앞서 nat-node-as-1, 2인스턴스 생성 시 입력한 태그인 nat-as를 입력하고
Next hop은 Specify an instance로 변경하여 인스턴스를 NAT gateway역할을 할 VM인스턴스 인 nat-gw-as로 선택하고 생성한다.
iptables을 통한 NAT gateway 구성
iptables란?
리눅스에서 사용하는 방화벽을 구성하는 유틸리티이다.
VM인스턴스 SSH접속
VM인스턴스 페이지에서 nat-gw-as VM의 오른쪽에 있는 SSH버튼을 통해 SSH터미널에 접속한다.
접속 후 다음 명령어를 실행하여 IP전송을 활성화 한다
%echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
이후, 다음 명령어를 실행하여 마스커레이드(MASQUERADE)를 활성화하여 사설IP를 외부 인터넷과 연결 가능하게 한다. (따로 표시되는 내용 없음)
%sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
앞서 구성한 TCP로드밸런싱이 적용된 웹 어플리케이션 서버들에 추가적으로 구성한 NAT gateway에 대한 구성이 완료되었다.
NAT gateway 적용이 완료된 네트워크 및 VM 구성도
NAT gateway 테스트
SSH를 통해 nat-node-as-1, 2에 접속
%ssh nat-node-as-1
nat-node-as-2도 같은 방식으로 접속한다. 만약 권한이 부족하다고 나오면 다음 두단계의 명령어를 실행해서 접속을 시도해보고
같은 zone에 생성하였기 때문에 접속시간은 거의 동일하며 서버에서 처리되는 시간과 대기시간에서 차이를 보인다. 앞서 설명한 것처럼 서브넷으로 웹 어플리케이션 서버를 구성하고, 또한 TCP네트워크 로드 밸런서를 이용하여 부하를 분산하기 때문에 나타난 결과이다.
서브넷을 통한 웹 어플리케이션 두대의 서버구성을 하였으며 또한 효율적인 트래픽 처리를 위해 부하를 분산하는 기능을 하는 네트워크 로드 밸런싱을 적용하였으며, 중간에 NAT gateway를 구성하여 외부 인터넷의 직접 연결을 차단하여, 보안성을 높인 구성을 하였다. 이러한 방법을 통해 웹 서버 구성을 조금 더 쉽게 할 수 있기를 바란다.
구글에 대해서 이야기를 할 때 수많은 서비스(검색, 지도, Apps, Gmail, YouTube, 등)뿐만 아니라 그러한 서비스들의 기반이 되는 수많은 데이터센터와 네트워크에 대해서 이견이 없는 한 그 어떤 기업도 따라오기 힘든 가장 강력한 인프라를 가진 회사라는 것에 대하여 인정 할 것이다. 앞서 언급한 구글의 내부 서비스뿐만 아니라 구글 클라우드에서 제공하는 네트워크 서비스에도 같은 인프라를 사용하고 있다. 이 글에서는 그러한 구글 클라우드에서 제공하는 기본적인 네트워크 서비스에 대해서 설명하고자 한다.
구글의 클라우드의 네트워크 인프라
구글 클라우드에 구축된 네트워크 기술인 주피터(Jupiter)는 초당 양방향 대역폭이 1페타비트 이상을 제공하며 최대 1.3Pbps을 지원한다. 메쉬구조인 클로스 토폴리지(Clos topology)를 적용하고 범용 스위치를 활용해 큰 규모의 스위치를 논리적으로 구현했다. 이를 효율적으로 제어하기 위해 중앙에서 제어하는 SDN(Software Defined Networking)을 구현했으며 오픈소스인 오픈 플로우(Open Flow)를 활용해 작동된다.
구글의 데이터센터들은 서로 광케이블 기반의 백본 네트워크로 묶여 있다. 또한 30개의 국가에 70개이상의 Points of presence(또는 Edge node)라고 해서 일종의 중계 서버를 배치하여 이 중계서버를 활용해 광케이블 네트워크를 사용할 수 있어서 글로벌 서비스 시에 거리에 따라 속도가 저하되는 일반 인터넷 망을 이용한 서비스에 비해 빠른 응답속도를 보장할 수 있다. (자세한 내용은 http://bcho.tistory.com/1109 참고)
리전과 존(Region / Zone)
리전은 지리적인 위치인 대륙 범위로 생각하면 될 것이다.
현재 미국 동부, 중앙과 유럽 서부와 아시아 동부 리전이 있다. 존은 각각의 리전(지역)에 실제로 위치한 데이터 센터이다.
네트워크의 구성요소 및 참고사항
구글 클라우드에서 내부 통신은 IPv4 유니캐스트(unicast)기반으로 통신하며, IPv6는 아직 지원되지 않는다.
네트워크와 프로젝트, 인스턴스의 관계
네트워크는 하나의 프로젝트안에 묶이고 하나의 프로젝트에 5개까지 생성 가능하다. 또한 VM인스턴스들은 하나의 네트워크안에 묶이고 하나의 네트워크에 다수의 VM을 연결할 수 있다.
VM인스턴스사이의 통신
각각의 VM들은 TCP, UDP, ICMP를 통해서만 통신한다.
네트워크 종류
네트워크 구성은 범위의 제약이 없는 하나의 글로벌 IP를 가지는 레거시 네트워크(legacy network) 또는 리전 범위의 서브넷(Subnet network)을 구성 할 수 있다.
레거시 네트워크의 경우 IP주소가 리전 또는 존 범위로 그룹화 되어있지 않다. (IP가 연속적이지 않다)
Legacy Networks (non-subnet) 예시
이미지 출처 : https://cloud.google.com/compute/docs/networking
서브넷의 경우 자동(auto)모드와 맞춤설정(custom)모드로 구성할 수 있으며 자동(auto)모드로 구성 시 미리 정의 된 IP범위(아래 이미지 참조)와 게이트웨이를 사용하여 서브넷이 구성된다.
맞춤설정(custom)모드로 서브넷을 구성 시에는 생성 시 리전범위에서 IP범위(10.0.0.0/8 또는 192.168.0.0/16이내)를 지정하여야 하며 0, 1또는 다수의 서브넷을 구성 할 수 있다. (프로제트 당 최대 100개)
Subnet network 예시
이미지 출처 : https://cloud.google.com/compute/docs/networking
레거시(legacy) 네트워크와 서브넷(subnet) 네트워크는 상호 변경이 불가능하다.
방화벽 규칙(Firewall-rules)
기본적으로 모든 Inbound(내부로 들어오는) 트래픽에 대해 막혀 있으며Allow 규칙만 생성 할 수 있다. (default네트워크의 경우 SSH연결을 위한 TCP 22번포트, RDP연결을 위한 TCP 3389포트 및 internal, icmp는 생성되어 있다)
IP Addresses
Internal IP : 모든 VM은 생성시 임시의 내부 IP를 가지고 있으며 이를 통해 같은 네트워크 상에서 포함된 VM인스턴스의 이름을 기반으로 내부VM들과 통신을 한다. subnet(auto/custom) 및 legacy 네트워크를 구성 시에 Internal IP에 적용된다.
아래 도식은 내부 및 외부와 통신하는 기본 구조를 나타낸 예이다.
External IP : 내부 및 외부(인터넷) 통신이 가능하며 VM생성 시에 임시(ephemeral)또는 고정(static)으로 생성하거나 없음(none)을 선택하여 외부IP(public IP) 없이 생성하고 앞서 설명한 내부IP(private IP)를 이용하여 로드밸런서를 통해 접근을 하게 하는 등의 방법을 이용하여 외부로의 접근을 차단하여 보안을 향상 시킬 수 있다. 또한 임시로 외부IP를 생성하고 고정IP로 변경도 가능하다.
아래 도식은 서로 다른 네트워크나 서로 다른 프로젝트에서의 VM간의 통신 예시이다.
**GCP내부에서의 서로 다른 프로젝트, 같은 프로젝트라도 서로 다른 네트워크에서 VM끼리 통신 시 External IP를 통해 통신을 하게 된다. 이 경우에도 외부 인터넷을 통하지 않고 구글 클라우드의 내부 광케이블 네트워크를 이용해서 통신하기 때문에 속도, 보안, 비용적인 부분에서의 이점을 얻을 수 있다.
Routes
네트워크에 연결된 글로벌 리소스이다. 각각의 VM인스턴스에 대해 읽기전용으로 생성된 라우팅 테이블이다.
VPN, many-to-one NAT, proxies구성 등에 사용된다.
네트워크 구성하기
가입하기
먼저 https://cloud.google.com/ 에 접속해서 Try It Free버튼을 클릭하여 로그인을 한 후, 해당되는 내용들을 입력하여 구글 클라우드 서비스에 가입을 한다.(신용카드 정보 입력 필요)
계정이 생성되면 자동으로 $300한도로 60일동안 사용할 수 있는 무료 평가판으로 이용 가능하다. ($300을 먼저 소모하거나 60일이 경과하면 소멸한다.)
신용 카드정보를 입력하지만 확인 용도이며, 사용자가 직접 업그레이드를 하지 않는 이상 비용이 결제 되지 않는다.
프로젝트 생성
구글 클라우드는 VM을 포함한 모든 서비스 자원들을 묶은 하나의 컨테이너 형태로 프로젝트라는 개념을 사용한다. 처음 무료 평가판을 등록하면 프로젝트가 없으니 새로 생성하여야 한다.
임의로 방화벽규칙명 : autonet으로 설정하였으며 프로토콜은 tcp22, 3389포트, udp, icmp를 지정하였고 IP범위를 아시아 리전의 사전 정의 범위인 10.140.0.0/20를 지정하였다. 단순 예시일 뿐이며 상황 및 조건에 따라 원하는 형태로 방화벽규칙을 생성 할 수 있다.
임의로 방화벽이름을 설정하고 –-network flag를 통해 네트워크를 지정하고 필요한 프로토콜 및 포트를 지정하여 방화벽규칙을 생성하면 된다. IP범위를 지정할 수 도 있다.
(참고 : gcloud 명령어 사용 시 다음 명령어가 기억이 안난다면 –-help를 입력하면 다음 명령어에 대한 정보를 얻을 수 있다.
예시
%gcloud –-help
%gcloud compute –-help
%gcloud compute networks –-help
경우에 따라서 –h로 입력해야 나올 수 있음)
다음 명령어를 통해 앞서 생성한 auto-networks를 확인 할 수 있다.
%gcloud compute networks subnets list –-sort-by NAME
여러 명의 사용자가 동시에 자원을 공유해서 사용해야 하는 기업 프로젝트 환경에서 리소스에 대한 접근 및 권한 관리는 선택이 아니라 필수이다. 구글의 클라우드에서 제공하는 IAM(Identity and Access Management)은 구글 클라우드 서비스들에 대한 편리하고 일관된 방식으로 통합적인 접근 제어를 제공한다.
IAM (Identity and Access Management) 이란?
구글 클라우드 서비스의 전체 리소스에 대해서 뿐만 아니라 통합적으로 사용자 또는 특정유형 별로 구글 클라우드 서비스 각각의 단위로 리소스의 접근 범위를 지정해서 해당 리소스에 대한 권한의 관리를 쉽게 할 수 있게 하는 서비스이다.
다른 예로, 리눅스의 Permissions은 파일, 디렉토리 단위로 적용한다면, IAM은 구글 클라우드의 서비스의 프로젝트 레벨에서의 전체 리소스 또는 세부적인 단위로 적용한다고 생각할 수 있다..
IAM의 필요성
예를들면, 만약에 어떤 기업에서 구글 클라우드 Compute Engine의 VM과 구글 클라우드 스토리지를 이용해서 미디어 서비스를 하고 있으며, 개발자 또는 엔지니어와 디자이너는 각각의 미디어파일과 소스코드의 정보는 공유가 필요하다면 디자이너에게 어플리케이션의 소스코드를 수정할 수 있는 권한을 줄 수도 없고 반대의 경우도 마찬가지 아닌가? 보안도 문제가 되고 안정적인 운영에도 문제가 될 수 있다. 이러한 문제들을 극복하기 위해 구글 클라우드에서 제공하는 권한 제어 서비스가 IAM이다.
먼저 구글 클라우드 IAM에서 권한을 부여할 수 있는 유형은 다음과 같다.
Google account
Service account
Google group
Google Apps domain
IAM 기본 유형 별 정의
먼저 구글 계정은 gmail계정이다. (예 : test@gmail.com)
다음으로 서비스 계정은 구글 클라우드 서비스에 대한 ID이며 하나의 ID로 다른 구글 클라우드 서비스에 접근할 수 있도록 해주는 이메일 형태의 계정이다. IAM관리 페이지에서 추가로 생성 가능하다. (기본 GCE, GAE 서비스 ID제공)
(예 : <project_id or project number>@developer.gserviceaccount.com 형식이며,
* 프로젝트의 식별자로 Project Name, ID, Number 세가지 제공되며 Unique한 값으로 생성하여야 하며 Number는 자동으로 부여된다. Project ID의 경우 APP Engine의 어플리케이션 ID로도 사용되며 프로젝트 삭제 시 다시 같은 ID로 생성할 수 없다.
구글 클라우드 IAM은 단순하며 유연한 역할을 제공한다.
기본적인 역할 모델로 보면 다음과 같다.
Viewer
Editor
Owner
먼저 뷰어는 말그대로 구글 클라우드 리소스를 보는 권한만 부여된다.
편집자는 보기 권한 + 리소스의 생성/삭제/변경이 추가된다.
마지막으로 소유자는 앞의 모든 권한을 가지면서 프로젝트 멤버 및 프로젝트 자체를 관리(추가/삭제)할 수 있는 권한이 부여된다.
*프로젝트 최초 생성시에 소유자레벨의 권한이 부여되어 있다.
*기본적인 역할 외에 프로젝트 레벨에서Service Account Actor가 있는데
서비스 별 세분화 한 역할을 지정하여 사용시에 서비스계정의 정보를 획득하고
인증 시 사용하여 보안성을 높인다. (서비스 단위로 권한 적용시 동시 사용)
추가적으로 결제와 관련한 부분은 Billing administrator(결제 관리자)를 통해 관리된다. 처음 프로젝트 생성 시에 소유자로 지정되어 있으며 리소스에 대한 권한은 제한된다.