컨테이너 최적화 배포 만들기

이 전체 예는 컨테이너 최적화 이미지를 사용하는 가상 머신으로 배포를 생성하는 방법을 설명합니다. Compute Engine에서 컨테이너를 사용하는 자세한 방법은 컨테이너 최적화 Compute Engine 이미지를 참조하세요.

여기서는 다음 방법을 안내합니다.

  1. 간단한 컨테이너 매니페스트를 만듭니다.
  2. 컨테이너 이미지를 사용하는 구성 및 템플릿을 만듭니다.
  3. 리소스를 배포하고 배포가 성공적인지 확인합니다.

컨테이너 매니페스트 만들기

컨테이너를 사용하려면 컨테이너 매니페스트를 정의해야 합니다. 매니페스트에서는 컨테이너 이미지, 시작할 컨테이너, 부팅 시 실행할 명령어, 사용 설정할 포트와 같은 속성을 설명합니다.

다음 콘텐츠로 container_manifest.yaml라는 파일을 만듭니다.

# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This is a container manifest, as described here:
#   https://cloud.google.com/compute/docs/containers/container_vms
apiVersion: v1
kind: Pod
metadata:
  name: simple-echo
spec:
  containers:
    - name: simple-echo
      image: gcr.io/google-samples/hello-app:2.0
      imagePullPolicy: Always
      ports:
        - containerPort: 8080
          hostPort: 8080

이 매니페스트는 Hello Application 컨테이너 이미지를 사용하고 포트 8080에서 리슨하는 echo 서버를 실행하는 simple-echo라는 컨테이너를 만듭니다.

템플릿 및 구성 만들기

다음으로 컨테이너 최적화 이미지로 가상 머신 인스턴스를 시작하는 템플릿을 만듭니다. 다음 콘텐츠로 container_vm.[jinja|py]라는 파일을 만듭니다.

Jinja



{% set COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/' %}
{% set BASE_NAME = env['deployment'] + '-' + env['name'] %}

{% macro GlobalComputeUrl(project, collection, name) -%}
{{ COMPUTE_URL_BASE }}projects/{{ project }}/global/{{ collection }}/{{ name }}
{%- endmacro %}

{% macro ZonalComputeUrl(project, zone, collection, name) -%}
{{ COMPUTE_URL_BASE }}projects/{{ project }}/zones/{{ zone }}/{{ collection }}/{{ name }}
{%- endmacro %}

resources:
- name: {{ BASE_NAME }}
  type: compute.v1.instance
  properties:
    zone: {{ properties['zone'] }}
    machineType: {{ ZonalComputeUrl(env['project'], properties['zone'], 'machineTypes', 'n1-standard-1') }}
    metadata:
      items:
        - key: gce-container-declaration
          value: |
            {{ imports[properties['containerManifest']]|indent(12) }}
    disks:
      - deviceName: boot
        type: PERSISTENT
        autoDelete: true
        boot: true
        initializeParams:
          diskName: {{ BASE_NAME }}-disk
          sourceImage: {{ GlobalComputeUrl('cos-cloud', 'images', properties['containerImage']) }}
    networkInterfaces:
      - accessConfigs:
          - name: external-nat
            type: ONE_TO_ONE_NAT
        network: {{ GlobalComputeUrl(env['project'],  'networks', 'default') }}
    serviceAccounts:
      - email: default
        scopes:
        - https://www.googleapis.com/auth/logging.write
        - https://www.googleapis.com/auth/monitoring.write

Python

# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Creates a Container VM with the provided Container manifest."""

COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/'

def GlobalComputeUrl(project, collection, name):
  return ''.join([COMPUTE_URL_BASE, 'projects/', project,
                  '/global/', collection, '/', name])

def ZonalComputeUrl(project, zone, collection, name):
  return ''.join([COMPUTE_URL_BASE, 'projects/', project,
                  '/zones/', zone, '/', collection, '/', name])

def GenerateConfig(context):
  """Generate configuration."""

  res = []
  base_name = (context.env['deployment'] + '-' +
               context.env['name'])

  # Properties for the container-based instance.
  instance = {
      'zone': context.properties['zone'],
      'machineType': ZonalComputeUrl(context.env['project'],
                                     context.properties['zone'],
                                     'machineTypes',
                                     'n1-standard-1'),
      'metadata': {
          'items': [{
              'key': 'gce-container-declaration',
              'value': context.imports[
                  context.properties['containerManifest']],
              }]
      },
      'disks': [{
          'deviceName': 'boot',
          'type': 'PERSISTENT',
          'autoDelete': True,
          'boot': True,
          'initializeParams': {
              'diskName': base_name + '-disk',
              'sourceImage': GlobalComputeUrl('cos-cloud',
                                              'images',
                                              context.properties[
                                                  'containerImage'])
              },
      }],
      'networkInterfaces': [{
          'accessConfigs': [{
              'name': 'external-nat',
              'type': 'ONE_TO_ONE_NAT'
              }],
          'network': GlobalComputeUrl(context.env['project'],
                                      'networks',
                                      'default')
      }],
      'serviceAccounts': [{
          'email': 'default',
          'scopes': [
            "https://www.googleapis.com/auth/logging.write",
            "https://www.googleapis.com/auth/monitoring.write"
          ]
      }]
  }
  res.append({
      'name': base_name,
      'type': 'compute.v1.instance',
      'properties': instance
  })
  # Resources to return.
  resources = {
      'resources': res,
  }

  return resources

템플릿의 구조를 적용하는 해당 스키마 파일을 만듭니다.

Jinja

# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

info:
  title: Container VM
  author: Google Inc.
  description: Creates a Container VM with the provided Container manifest.

required:
  - zone
  - containerImage
  - containerManifest

properties:
  zone:
    description: Zone in which this VM will run
    type: string
  containerImage:
    description: Name of the Google Cloud Container VM Image
    type: string
  containerManifest:
    description: String containing the Container Manifest in YAML
    type: string

Python

# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

info:
  title: Container VM
  author: Google Inc.
  description: Creates a Container VM with the provided Container manifest.

required:
  - zone
  - containerImage
  - containerManifest

properties:
  zone:
    description: Zone in which this VM will run
    type: string
  containerImage:
    description: Name of the Google Cloud Container VM Image
    type: string
  containerManifest:
    description: String containing the Container Manifest in YAML
    type: string

이 템플릿에는 다음을 비롯한 많은 매개변수가 정의되어 있습니다.

  • deployment, name, project 환경 변수. Deployment Manager는 사용자의 추가 작업 없이 이러한 변수를 자동으로 채웁니다.
  • 구성에서 정의될 zone, containerImage, containerManifest 속성

다음과 같이 container_vm.yaml이라는 구성 파일을 만듭니다.

Jinja

# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

imports:
- path: ../../common/container_manifest.yaml
  name: container_manifest
- path: container_vm.jinja

resources:
  - name: my-container-vm
    type: container_vm.jinja
    properties:
      zone: ZONE_TO_RUN
      containerImage: family/cos-stable
      containerManifest: container_manifest

Python

# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

imports:
- path: ../../common/container_manifest.yaml
  name: container_manifest
- path: container_vm.py

resources:
  - name: my-container-vm
    type: container_vm.py
    properties:
      zone: ZONE_TO_RUN
      containerImage: family/cos-stable
      containerManifest: container_manifest

ZONE_TO_RUN을 원하는 가상 머신 영역으로 바꿔야 합니다. 이 파일은 사용할 컨테이너 이미지와 이전에 만든 컨테이너 매니페스트도 정의했습니다.

가상 머신 인스턴스 배포

마지막으로 Google Cloud CLI를 사용하여 가상 머신 인스턴스를 배포합니다.

gcloud deployment-manager deployments create my-container-deployment \
  --config container_vm.yaml

배포가 생성되면 배포 세부정보를 확인할 수 있습니다. 예를 들면 다음과 같습니다.

$ gcloud deployment-manager deployments describe my-container-deployment
creationTimestamp: '2015-04-02T12:24:31.645-07:00'
fingerprint: ''
id: '8602410885927938432'
manifest: https://www.googleapis.com/deploymentmanager/v2/projects/myproject/global/deployments/my-container-deployment/manifests/manifest-1428002671645
name: my-container-deployment
state: DEPLOYED
resources:
NAME                                     TYPE                 ID                   UPDATE_STATE  ERRORS
my-container-deployment-my-container-vm  compute.v1.instance  3775082612632070557  COMPLETED     -

인스턴스가 실행 중인지 확인

컨테이너 인스턴스가 시작되었는지 테스트하려면 브라우저에서 hello world를 인쇄할 가상 머신의 외부 IP 주소에 방문합니다.

  1. 포트 8080을 통해 가상 머신에서 트래픽 쿼리를 허용하도록 Compute Engine 방화벽 규칙을 추가합니다.

    gcloud compute firewall-rules create allow-8080 --allow tcp:8080
    
  2. 인스턴스의 외부 IP 주소를 가져옵니다.

    $ gcloud compute instances describe my-container-deployment-my-container-vm
    ...
    name: my-container-vm-my-container-deployment
    networkInterfaces:
    - accessConfigs:
      - kind: compute#accessConfig
        name: external-nat
        natIP: 104.197.8.138
        type: ONE_TO_ONE_NAT
      name: nic0
      network: https://www.googleapis.com/compute/v1/projects/myproject/global/networks/default
      networkIP: 10.240.97.220
    scheduling:
      automaticRestart: true
      onHostMaintenance: MIGRATE
    selfLink: https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/my-container-deployment-my-container-vm
    status: RUNNING
    tags:
      fingerprint: 42WmSpB8rSM=
    zone: https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a
    ...

    이 경우 외부 IP는 104.197.8.138입니다.

  3. 브라우저 창에서 브라우저 주소 표시줄에 외부 IP와 포트 8080을 입력합니다. 예를 들면 104.197.8.138:8080입니다.

    성공하면 hello world 메시지가 표시됩니다.

(선택사항) 배포 삭제

비용을 절약하고 배포를 더 이상 원하거나 필요로 하지 않는 경우, 배포를 삭제하세요.

gcloud deployment-manager deployments delete my-container-deployment

다음 단계

전체 사용자 가이드에서 또는 API를 통해 Deployment Manager에 대해 자세히 알아봅니다.

다른 가이드를 사용해 보세요.