Skip to main content

Container-Optimized OS Should Be Enabled

More Info:

Ensures all Kubernetes cluster nodes have Container-Optimized OS enabled. Container-Optimized OS is optimized to enhance node security. It is backed by a team at Google that can quickly patch it.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS GKE

Triage and Remediation

Remediation

Using Console

To remediate the misconfiguration of "Container-Optimized OS Should Be Enabled" in GCP, you can follow the below steps using the GCP console:

  1. Open the GCP Console and go to the Compute Engine page.
  2. Select the instance for which you want to enable Container-Optimized OS.
  3. Click on the "Edit" button on the top of the page.
  4. Scroll down to the "Cloud API access scopes" section.
  5. Expand the "Compute Engine default service account" section.
  6. Click on the "Set access for each API" button.
  7. In the "Compute Engine" section, select the "Read Write" access level.
  8. Click on the "Save" button to save the changes.
  9. Scroll up to the "Boot disk" section.
  10. Click on the "Change" button.
  11. In the "Operating system" section, select "Container-Optimized OS".
  12. Click on the "Select" button to save the changes.
  13. Click on the "Save" button to apply the changes to the instance.

Once the above steps are completed, the Container-Optimized OS will be enabled for the selected instance.

Using CLI

To enable Container-Optimized OS on GCP using GCP CLI, follow these steps:

  1. Open the Cloud Shell on the GCP Console.
  2. Run the following command to enable the Container-Optimized OS:
gcloud compute instances create [INSTANCE_NAME] \
--image-project cos-cloud \
--image-family cos-stable \
--boot-disk-size [DISK_SIZE] \
--boot-disk-type pd-standard \
--boot-disk-device-name [DEVICE_NAME]

Replace [INSTANCE_NAME] with the name of the instance that you want to enable Container-Optimized OS on, [DISK_SIZE] with the size of the boot disk in GB, and [DEVICE_NAME] with the name of the boot disk device.

  1. Once the instance is created, SSH into the instance and verify that Container-Optimized OS is enabled by running the following command:
cat /etc/os-release

This command should output information about the OS, including the line "ID=cos".

That's it! Container-Optimized OS is now enabled on your GCP instance.

Using Python

To remediate the misconfiguration of "Container-Optimized OS Should Be Enabled" in GCP using Python, you can follow the below steps:

  1. Import the necessary libraries:
from googleapiclient.discovery import build
from google.oauth2 import service_account
  1. Set the project ID and the service account credentials:
project_id = "<PROJECT_ID>"
credentials = service_account.Credentials.from_service_account_file('<SERVICE_ACCOUNT_KEY_FILE_PATH>')
  1. Build the GCP Compute Engine API client:
compute_client = build('compute', 'v1', credentials=credentials)
  1. Get the list of instances in the project:
instances = compute_client.instances().list(project=project_id, zone='<ZONE>').execute()
  1. Loop through the instances and check if the Container-Optimized OS is enabled:
for instance in instances['items']:
instance_name = instance['name']
instance_id = instance['id']
instance_zone = instance['zone'].split('/')[-1]

# Get the instance metadata
metadata = compute_client.instances().get(project=project_id, zone=instance_zone, instance=instance_name).execute()['metadata']['items']

# Check if Container-Optimized OS is enabled
cos_enabled = False
for item in metadata:
if item['key'] == 'google-container-os':
if item['value'] == 'true':
cos_enabled = True
break

# If Container-Optimized OS is not enabled, enable it
if not cos_enabled:
metadata.append({
'key': 'google-container-os',
'value': 'true'
})
compute_client.instances().update(project=project_id, zone=instance_zone, instance=instance_name, body={
'metadata': {
'items': metadata
}
}).execute()
print(f"Container-Optimized OS enabled for instance {instance_name} (ID: {instance_id}) in zone {instance_zone}")
else:
print(f"Container-Optimized OS already enabled for instance {instance_name} (ID: {instance_id}) in zone {instance_zone}")

This code will check all the instances in the specified zone of the project and enable the Container-Optimized OS if it is not already enabled.

Using Terraform
resource "google_container_cluster" "PRIMARY_CLUSTER" {
name = "PRIMARY_CLUSTER_NAME" # replace with your cluster name
location = "GCP_REGION_OR_ZONE" # e.g. "us-central1" or "us-central1-a"

# This affects the default node pool that Terraform creates with the cluster
remove_default_node_pool = false
initial_node_count = 1

node_config {
# Enable Container-Optimized OS for nodes in the default node pool
image_type = "COS_CONTAINERD"
machine_type = "e2-medium"

oauth_scopes = [
"https://www.googleapis.com/auth/cloud-platform",
]
}

network = "projects/PROJECT_ID/global/networks/NETWORK_NAME" # replace PROJECT_ID/NETWORK_NAME
subnetwork = "projects/PROJECT_ID/regions/REGION/subnetworks/SUBNET_NAME"
}

# If you manage separate node pools instead of using the default, set COS here too:
resource "google_container_node_pool" "PRIMARY_NODE_POOL" {
name = "PRIMARY_NODE_POOL_NAME" # replace with your node pool name
cluster = google_container_cluster.PRIMARY_CLUSTER.name
location = google_container_cluster.PRIMARY_CLUSTER.location
node_count = 3

node_config {
# Enable Container-Optimized OS for nodes in this pool
image_type = "COS_CONTAINERD"
machine_type = "e2-medium"

oauth_scopes = [
"https://www.googleapis.com/auth/cloud-platform",
]
}
}

Changing image_type on an existing node pool causes the nodes in that pool to be replaced (a rolling node recreation; workloads will be rescheduled). Plan carefully for any disruption-sensitive workloads.

Verification: terraform plan should show image_type changing from the previous value (for example "UBUNTU_CONTAINERD") to "COS_CONTAINERD" on all node pools.

Additional Reading: