Creating a Container-Optimized Deployment

This full example describes how to create a deployment with a virtual machine that uses a container-optimized image. For more information on using containers with Compute Engine, see Container-Optimized Compute Engine Images .

This walk-through describes how to:

  1. Create a simple container manifest.
  2. Create a configuration and template that uses a container image.
  3. Deploy your resources and verify that the deployment was successful.

Create a container manifest

To use containers, you must define a container manifest. The manifest describes properties such as the container image, containers to launch, commands to execute on boot, and ports to enable.

Create a file named container_manifest.yaml with the following contents:

  # 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 
 

This manifest creates a container named simple-echo that uses the Hello Application container image and launches an echo server that listens on port 8080.

Create a template and configuration

Next, create a template that launches a virtual machine instance with a container-optimized image. Create a file named container_vm.[jinja|py] with the following contents:

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 
 

Create the corresponding schema file , which enforces the structure of the template:

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 
 

Notice there are a number of parameters defined in this template including:

  • The deployment , name , and project environment variables. Deployment Manager automatically populates those variables without additional action from you.
  • The zone , containerImage , and containerManifest properties, which will be defined in the configuration.

Create a configuration file named container_vm.yaml that looks like the following:

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 
 

Make sure to replace ZONE_TO_RUN with the desired zone for your virtual machine. Notice that the file has also defined the container image to use and the container manifest that you created earlier.

Deploy your virtual machine instance

Finally, deploy your virtual machine instance using the Google Cloud CLI:

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

Once the deployment has been created, you can view the details of your deployment. For example:

 $ 
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     -

Verify that your instance is running

To test that your container instance started up, visit the virtual machine's external IP address in your browser, which should print hello world :

  1. Add a Compute Engine firewall rule to allow you to query traffic on the virtual machine through port 8080:

     gcloud compute firewall-rules create allow-8080 --allow tcp:8080 
    
  2. Get your instance's external IP address:

     $ 
    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
    ...

    In this case, the external IP is 104.197.8.138 .

  3. In a browser window, enter in the external IP and port 8080 in the browser bar. For example, 104.197.8.138:8080 .

    If successful, you should see a hello world message.

(Optional) Delete your deployment

If you want to save on costs and no longer want or need your deployment, delete your deployment.

 gcloud deployment-manager deployments delete my-container-deployment 

What's next

Explore more about Deployment Manager in the Complete User Guides or through the API .

Try out some other tutorials:

Create a Mobile Website
View Site in Mobile | Classic
Share by: