[Yandex Cloud documentation](../../index.md) > [Yandex Managed Service for Kubernetes](../index.md) > [Tutorials](index.md) > Using Container Registry > Integration with Container Registry

# Integration with Container Registry


[Yandex Container Registry](../../container-registry/index.md) offers storage and distribution of [Docker images](../../container-registry/concepts/docker-image.md). By integrating it, you enable Managed Service for Kubernetes to run [pods](../concepts/index.md#pod) with applications from Docker images stored in the [Container Registry](../../container-registry/concepts/registry.md). To use Container Registry, [set up](#config-ch) a Docker credential helper. It enables access to private registries using a [service account](../../iam/concepts/users/service-accounts.md).

To integrate Managed Service for Kubernetes with Container Registry:
1. [Create service accounts](#create-sa).
   1. [Create a service account for resources](#res-sa).
   1. [Create a service account for Managed Service for Kubernetes nodes](#node-sa).
1. [Create security groups](#create-sg).
1. [Create the required Kubernetes resources](#create-k8s-res).
   1. [Create a Managed Service for Kubernetes cluster](#create-cluster).
   1. [Create a Managed Service for Kubernetes node group](#create-node-groups).
1. [Create the required Container Registry resources](#create-cr-res).
   1. [Create a registry](#registry-create).
   1. [Configure a credential helper](#config-ch).
   1. [Set up a Docker image](#docker-image).
1. [Connect to the Managed Service for Kubernetes cluster](#cluster-connect).
1. [Run the test app](#test-app).
1. [Delete the resources you created](#delete-resources).

## Getting started {#before-you-begin}

Go to the Yandex Cloud [management console](https://console.yandex.cloud) and select the folder where you want to perform the operations. If that folder does not exist, create it:

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), in the top panel, click ![image](../../_assets/console-icons/layout-side-content-left.svg) or ![image](../../_assets/console-icons/chevron-down.svg) and select the [cloud](../../resource-manager/concepts/resources-hierarchy.md#cloud).
  1. To the right of the cloud name, click ![image](../../_assets/console-icons/ellipsis.svg).
  1. Select ![image](../../_assets/console-icons/plus.svg) **Create folder**.
  
     ![create-folder1](../../_assets/resource-manager/create-folder-1.png)
  
  1. Give your [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) a name. The naming requirements are as follows:
  
      * Length: between 3 and 63 characters.
      * It can only contain lowercase Latin letters, numbers, and hyphens.
      * It must start with a letter and cannot end with a hyphen.
  
  1. Optionally, specify the description for your folder.
  1. Select **Create a default network**. This will create a [network](../../vpc/concepts/network.md#network) with subnets in each availability zone. Within this network, you will also have a [default security group](../../vpc/concepts/security-groups.md#default-security-group), within which all network traffic will be allowed.
  1. Click **Create**.
  
     ![create-folder2](../../_assets/resource-manager/create-folder-2.png)

- CLI {#cli}

  If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../cli/quickstart.md#install).

  1. View the description of the create folder command:

      ```bash
      yc resource-manager folder create --help
      ```

  1. Create a new folder:

      * with a name and without a description:

          ```bash
          yc resource-manager folder create \
             --name new-folder
          ```

          * Length: between 3 and 63 characters.
          * It can only contain lowercase Latin letters, numbers, and hyphens.
          * It must start with a letter and cannot end with a hyphen.

      * with a name and description:

          ```bash
          yc resource-manager folder create \
             --name new-folder \
             --description "my first folder with description"
          ```

- API {#api}

  Use the [create](../../resource-manager/api-ref/Folder/create.md) method for the [Folder](../../resource-manager/api-ref/Folder/index.md) resource of the Yandex Resource Manager service.

{% endlist %}


### Required paid resources {#paid-resources}

The support cost for this solution includes:

* Fee for using the master and outgoing traffic in a Managed Service for Kubernetes cluster (see [Managed Service for Kubernetes pricing](../pricing.md)).
* Fee for using computing resources, OS, and storage in cluster nodes (VMs) (see [Compute Cloud pricing](../../compute/pricing.md)).
* Fee for public IP addresses assigned to cluster nodes (see [Virtual Private Cloud pricing](../../vpc/pricing.md#prices-public-ip)).
* Fee for Container Registry [storage](../../container-registry/pricing.md).


## Create service accounts {#create-sa}

Create these [service accounts](../../iam/operations/sa/create.md):
* Service account for resources with the `k8s.clusters.agent` and `vpc.publicAdmin` [roles](../security/index.md#yc-api) for the [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) to host the new Managed Service for Kubernetes cluster. This service account will be used to create Managed Service for Kubernetes cluster resources.
* Service account for [Managed Service for Kubernetes nodes](../concepts/index.md#node-group) with the [container-registry.images.puller](../../container-registry/security/index.md#choosing-roles) role for the folder containing the Docker image registry. The Managed Service for Kubernetes nodes will use this account to pull the required Docker images from the registry.

### Create a service account for resources {#res-sa}

To create a service account that will be used to create the resources for the Managed Service for Kubernetes cluster:
1. Save the folder ID from your CLI profile configuration to a variable:

   {% list tabs group=programming_language %}

   - Bash {#bash}

     ```bash
     FOLDER_ID=$(yc config get folder-id)
     ```

   - PowerShell {#powershell}

     ```shell script
     $FOLDER_ID = yc config get folder-id
     ```

   {% endlist %}

1. Create a service account:

   {% list tabs group=programming_language %}

   - Bash {#bash}

     ```bash
     yc iam service-account create --name k8s-res-sa-$FOLDER_ID
     ```

   - PowerShell {#powershell}

     ```shell script
     yc iam service-account create --name k8s-res-sa-$FOLDER_ID
     ```

   {% endlist %}

1. Save the service account ID to a variable:

   {% list tabs group=programming_language %}

   - Bash {#bash}

     ```bash
     RES_SA_ID=$(yc iam service-account get --name k8s-res-sa-${FOLDER_ID} --format json | jq .id -r)
     ```

   - PowerShell {#powershell}

     ```shell script
     $RES_SA_ID = (yc iam service-account get --name k8s-res-sa-$FOLDER_ID --format json | ConvertFrom-Json).id
     ```

   {% endlist %}

1. Assign the [k8s.clusters.agent](../security/index.md#k8s-clusters-agent) role for the folder to the service account:

   ```bash
   yc resource-manager folder add-access-binding \
     --id $FOLDER_ID \
     --role k8s.clusters.agent \
     --subject serviceAccount:$RES_SA_ID
   ```

1. Assign the [vpc.publicAdmin](../../vpc/security/index.md#vpc-public-admin) role for the folder to the service account:

   ```bash
   yc resource-manager folder add-access-binding \
     --id $FOLDER_ID \
     --role vpc.publicAdmin \
     --subject serviceAccount:$RES_SA_ID
   ```

### Create a service account for cluster nodes {#node-sa}

To create a service account the Managed Service for Kubernetes nodes will use to pull the required Docker images from the registry:
1. Save the folder ID from your CLI profile configuration to a variable:

   {% list tabs group=programming_language %}

   - Bash {#bash}

     ```bash
     FOLDER_ID=$(yc config get folder-id)
     ```

   - PowerShell {#powershell}

     ```shell script
     $FOLDER_ID = yc config get folder-id
     ```

   {% endlist %}

1. Create a service account:

   {% list tabs group=programming_language %}

   - Bash {#bash}

     ```bash
     yc iam service-account create --name k8s-node-sa-$FOLDER_ID
     ```

   - PowerShell {#powershell}

     ```shell script
     yc iam service-account create --name k8s-node-sa-$FOLDER_ID
     ```

   {% endlist %}

1. Save the service account ID to a variable:

   {% list tabs group=programming_language %}

   - Bash {#bash}

     ```bash
     NODE_SA_ID=$(yc iam service-account get --name k8s-node-sa-${FOLDER_ID} --format json | jq .id -r)
     ```

   - PowerShell {#powershell}

     ```shell script
     $NODE_SA_ID = (yc iam service-account get --name k8s-node-sa-$FOLDER_ID --format json | ConvertFrom-Json).id
     ```

   {% endlist %}

1. Assign the [container-registry.images.puller](../../container-registry/security/index.md#choosing-roles) role for the folder to the service account:

   ```bash
   yc resource-manager folder add-access-binding \
     --id $FOLDER_ID \
     --role container-registry.images.puller \
     --subject serviceAccount:$NODE_SA_ID
   ```

## Create security groups {#create-sg}

[Create security groups](../operations/connect/security-groups.md) for the Managed Service for Kubernetes cluster and its node groups.

{% note warning %}

The configuration of security groups determines performance and availability of the cluster and the services and applications running in it.

{% endnote %}

## Set up Kubernetes resources {#create-k8s-res}

## Set up Kubernetes resources {#create-k8s-res}

### Create a Managed Service for Kubernetes cluster {#create-cluster}

{% note tip %}

This example uses the basic cluster parameters. Once the cluster is created, you cannot change some of its settings, e.g., [Container Network Interface](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) you selected, [secret encryption](../concepts/encryption.md#k8s-secrets-encryption) using Yandex Key Management Service, and a number of others. We recommend checking out [our detailed guide on creating a Managed Service for Kubernetes cluster](../operations/kubernetes-cluster/kubernetes-cluster-create.md#kubernetes-cluster-create).

{% endnote %}

Create a [Managed Service for Kubernetes cluster](../concepts/index.md#kubernetes-cluster) and specify the previously created [service accounts](../../iam/concepts/users/service-accounts.md) in the `--service-account-id` and `--node-service-account-id` parameters, and security groups in the `--security-group-ids` parameter.

{% list tabs group=programming_language %}

- Bash {#bash}

  Run this command:

  ```bash
  yc managed-kubernetes cluster create \
    --name k8s-demo \
    --network-name yc-auto-network \
    --zone ru-central1-a \
    --subnet-name yc-auto-subnet-0 \
    --public-ip \
    --service-account-id $RES_SA_ID \
    --node-service-account-id $NODE_SA_ID \
    --security-group-ids <security_group_IDs>
  ```

- PowerShell {#powershell}

  Run this command:

  ```shell script
  yc managed-kubernetes cluster create `
    --name k8s-demo `
    --network-name yc-auto-network `
    --zone ru-central1-a `
    --subnet-name yc-auto-subnet-0 `
    --public-ip `
    --service-account-id $RES_SA_ID `
    --node-service-account-id $NODE_SA_ID `
    --security-group-ids <security_group_IDs>
  ```

{% endlist %}

### Create a Managed Service for Kubernetes node group {#create-node-groups}

{% note warning %}

To access the Container Registry, a public IP address must be assigned to cluster nodes. Alternatively, a [NAT gateway](../../vpc/operations/create-nat-gateway.md) or [NAT instance](../../vpc/tutorials/nat-instance/index.md) must be configured in the node subnet.

For more information, see [Internet access for cluster worker nodes](../concepts/network.md#nodes-internet).

{% endnote %}

1. Make sure the Managed Service for Kubernetes cluster has been created successfully.
   1. In the [management console](https://console.yandex.cloud), select the [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) where you created the Managed Service for Kubernetes cluster.
   1. Navigate to **Managed Service for&nbsp;Kubernetes**.
   1. Make sure the Managed Service for Kubernetes cluster has been created successfully:
      * The **Status** column should state `Running`.
      * The **State** column should state `Healthy`.
1. Create a [Managed Service for Kubernetes node group](../concepts/index.md#node-group) and specify the previously created security groups in the `--network-interface security-group-ids` parameter:

   {% list tabs group=programming_language %}

   - Bash {#bash}

     ```bash
     yc managed-kubernetes node-group create \
       --name k8s-demo-ng \
       --cluster-name k8s-demo \
       --platform standard-v3 \
       --cores 2 \
       --memory 4 \
       --core-fraction 50 \
       --disk-type network-ssd \
       --fixed-size 2 \
       --network-interface subnets=yc-auto-subnet-0,ipv4-address=nat,security-group-ids=[<security_group_IDs>] \
       --async
     ```

   - PowerShell {#powershell}

     ```shell script
     yc managed-kubernetes node-group create `
       --name k8s-demo-ng `
       --cluster-name k8s-demo `
       --platform standard-v3 `
       --cores 2 `
       --memory 4 `
       --core-fraction 50 `
       --disk-type network-ssd `
       --fixed-size 2 `
       --network-interface subnets=yc-auto-subnet-0,ipv4-address=nat,security-group-ids=[<security_group_IDs>] `
       --async
     ```

   {% endlist %}

## Set up Container Registry resources {#create-cr-res}

### Create a registry {#registry-create}

Create a container registry:

```bash
yc container registry create --name yc-auto-cr
```

### Configure a Docker credential helper {#config-ch}

To simplify authentication in Container Registry, configure a [Docker credential helper](../../container-registry/operations/authentication.md#cred-helper). It enables you to use private Yandex Cloud registries without running the `docker login` command.

To configure a credential helper, run this command:

```bash
yc container registry configure-docker
```

### Set up a Docker image {#docker-image}

Build a Docker image and push it to the registry.
1. Create a Dockerfile named `hello.dockerfile` and paste the following lines into it:

   ```bash
   FROM ubuntu:latest
   CMD echo "Hi, I'm inside"
   ```

1. Build the Docker image.
   1. Get the ID of the [previously created](#registry-create) registry and save it to a variable:

      {% list tabs group=programming_language %}

      - Bash {#bash}

        ```bash
        REGISTRY_ID=$(yc container registry get --name yc-auto-cr --format json | jq .id -r)
        ```

      - PowerShell {#powershell}

        ```shell script
        $REGISTRY_ID = (yc container registry get --name yc-auto-cr --format json | ConvertFrom-Json).id
        ```

      {% endlist %}

   1. Build the Docker image:

      ```
      docker build . -f hello.dockerfile -t cr.yandex/$REGISTRY_ID/ubuntu:hello
      ```

   1. Push the Docker image to the registry:

      ```
      docker push cr.yandex/${REGISTRY_ID}/ubuntu:hello
      ```

1. Make sure the image is now in the registry:

   ```bash
   yc container image list
   ```

   Result:

   ```text
   +----------------------+---------------------+-----------------------------+-------+-----------------+
   |          ID          |       CREATED       |            NAME             | TAGS  | COMPRESSED SIZE |
   +----------------------+---------------------+-----------------------------+-------+-----------------+
   | crpa2mf008mp******** | 2019-11-20 11:52:17 | crp71hkgiolp********/ubuntu | hello | 27.5 MB         |
   +----------------------+---------------------+-----------------------------+-------+-----------------+
   ```

## Connect to the Managed Service for Kubernetes cluster {#cluster-connect}

[Install kubect](https://kubernetes.io/docs/tasks/tools/install-kubectl) and [configure it to work with the new cluster](../operations/connect/index.md#kubectl-connect).

## Run the test app {#test-app}

Run the pod with the app from the Docker image and make sure no additional authentication in Container Registry was required to push the Docker image.
1. Run the pod with the app from the Docker image:

   ```
   kubectl run --attach hello-ubuntu --image cr.yandex/${REGISTRY_ID}/ubuntu:hello
   ```

1. Check the running pod and view its full name:

   ```
   kubectl get po
   ```

   Result:

   ```
   NAME                           READY  STATUS     RESTARTS  AGE
   hello-ubuntu-5847fb9***-*****  0/1    Completed  3         61s
   ```

1. Check the logs of the container running on that pod:

   ```
   kubectl logs hello-ubuntu-5847fb9***-*****
   ```

   Result:

   ```
   Hi, I'm inside
   ```

   The pod pulled the Docker image with no additional authentication required on the Container Registry side.

## Delete the resources you created {#delete-resources}

Some resources are not free of charge. Delete the resources you no longer need to avoid paying for them:
1. Delete the Managed Service for Kubernetes cluster:

   ```bash
   yc managed-kubernetes cluster delete --name k8s-demo
   ```

1. Delete the service accounts:

   {% note warning %}

   Do not delete the service account until you delete the Managed Service for Kubernetes cluster.

   {% endnote %}

   - Delete the service account for resources:

     ```bash
     yc iam service-account delete --id $RES_SA_ID
     ```

   - Delete the service account for Managed Service for Kubernetes nodes:

     ```bash
     yc iam service-account delete --id $NODE_SA_ID
     ```

1. Delete the Container Registry resources.
   1. Get the name of the Docker image pushed to the registry:

      {% list tabs group=programming_language %}

      - Bash {#bash}

        ```bash
        IMAGE_ID=$(yc container image list --format json | jq .[0].id -r)
        ```

      - PowerShell {#powershell}

        ```shell script
        $IMAGE_ID = (yc container image list --format json | ConvertFrom-Json).id
        ```

      {% endlist %}

   1. Delete the Docker image:

      ```bash
      yc container image delete --id $IMAGE_ID
      ```

   1. Delete the registry:

      ```bash
      yc container registry delete --name yc-auto-cr
      ```

#### See also {#see-also}

* [Docker image in Container Registry](../../container-registry/concepts/docker-image.md)
* [Authentication in Container Registry](../../container-registry/operations/authentication.md)
* [Step-by-step guides for Container Registry](../../container-registry/operations/index.md)