יצירת פריסה שמותאמת לקונטיינרים

בדוגמה המלאה הזו מוסבר איך ליצור פריסה עם מכונה וירטואלית שמשתמשת בתמונה שעברה אופטימיזציה לקונטיינר. למידע נוסף על שימוש בקונטיינרים עם 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

קובץ המניפסט הזה יוצר קונטיינר בשם simple-echo שמשתמש בקובץ האימג' של הקונטיינר Hello Application ומפעיל שרת echo שמקשיב ביציאה 8080.

יצירה של תבנית והגדרה

לאחר מכן, יוצרים תבנית שמפעילה מכונה וירטואלית עם תמונה שעברה אופטימיזציה לקונטיינר. יוצרים קובץ בשם 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     -

בדיקה שהמופע פועל

כדי לבדוק שהפעלתם את מופע הקונטיינר, נכנסים לכתובת ה-IP החיצונית של המכונה הווירטואלית בדפדפן. אמור להופיע הפלט hello world:

  1. מוסיפים כלל של חומת אש ב-Compute Engine כדי לאפשר לכם לשלוח שאילתות לגבי תעבורת נתונים במכונה הווירטואלית דרך יציאה 8080:

    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

המאמרים הבאים

מידע נוסף על Deployment Manager זמין במדריכים למשתמש או דרך ה-API.

כדאי לנסות מדריכים אחרים: