[Yandex Cloud documentation](../../index.md) > [Yandex Managed Service for Kubernetes](../index.md) > [Step-by-step guides](index.md) > Network scenarios > Configuring the Calico network policy controller

# Configuring the Calico network policy controller

[Calico](https://www.projectcalico.org/) is an open-source plugin for Kubernetes that can be used to manage Kubernetes network policies. Calico extends the standard features of Kubernetes [network policies](../concepts/network-policy.md), which enables you to:
* Apply policies to any object: [pod](../concepts/index.md#pod), container, [virtual machine](../../compute/concepts/vm.md), or interface.
* Specify a particular action in the policy rules: deny, allow, or log.
* Specify as a target or a source: port, port range, protocols, HTTP and ICMP attributes, [IP address](../../vpc/concepts/address.md) or [subnet](../../vpc/concepts/network.md#subnet), and other objects.
* Regulate traffic using DNAT settings and traffic forwarding policies.

To configure the Calico network policy controller:
1. [Create an nginx service](#create-pod).
1. [Isolate pods using network policies](#enable-isolation).
1. [Create network policies enabling service access](#create-policy).

If you no longer need the resources you created, [delete them](#clear-out).

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

1. Create an infrastructure:

   {% list tabs group=instructions %}

   - Manually {#manual}

     1. Create a [cloud network](../../vpc/operations/network-create.md) and [subnet](../../vpc/operations/subnet-create.md).

         {% note warning %}
         
         Do not change or delete Virtual Private Cloud resources used by the Managed Service for Kubernetes cluster. This may cause cluster errors or make it impossible to delete later.
         
         {% endnote %}

     1. [Create security groups](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 %}

     1. [Create a Managed Service for Kubernetes cluster](kubernetes-cluster/kubernetes-cluster-create.md) and a [node group](node-group/node-group-create.md) with any suitable configuration. When creating it, specify the network, subnet, and security groups you prepared earlier. Also, enable the Calico network policy controller in the cluster:
        * In the management console, by selecting **Сalico CNI**.
        * Using the CLI, by setting the `--enable-network-policy` flag.
        * Using the [create](../managed-kubernetes/api-ref/Cluster/create.md) method for the [Cluster](../managed-kubernetes/api-ref/Cluster/index.md) resource.

   - Terraform {#tf}

     1. If you do not have Terraform yet, [install it](../../tutorials/infrastructure-management/terraform-quickstart.md#install-terraform).
     1. [Get the authentication credentials](../../tutorials/infrastructure-management/terraform-quickstart.md#get-credentials). You can add them to environment variables or specify them later in the provider configuration file.
     1. [Configure and initialize a provider](../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider). There is no need to create a provider configuration file manually, you can [download it](https://github.com/yandex-cloud-examples/yc-terraform-provider-settings/blob/main/provider.tf).
     1. Place the configuration file in a separate working directory and [specify the parameter values](../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider). If you did not add the authentication credentials to environment variables, specify them in the configuration file.

     1. Download the [k8s-calico.tf](https://github.com/yandex-cloud-examples/yc-mk8s-calico/blob/main/k8s-calico.tf) configuration file of the [Managed Service for Kubernetes cluster](../concepts/index.md#kubernetes-cluster) to the same working directory. This file describes:
        * [Network](../../vpc/operations/network-create.md) with a subnet.

            {% note warning %}
            
            Do not change or delete Virtual Private Cloud resources used by the Managed Service for Kubernetes cluster. This may cause cluster errors or make it impossible to delete later.
            
            {% endnote %}

        * Managed Service for Kubernetes cluster.
        * [Service account](../../iam/concepts/users/service-accounts.md) for the Managed Service for Kubernetes cluster and [node group](../concepts/index.md#node-group).
        * [Security groups](../../vpc/concepts/security-groups.md) which contain [rules](connect/security-groups.md) required 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 %}

     1. Specify the following in the configuration file:
        * [Folder ID](../../resource-manager/operations/folder/get-id.md).
        * [Kubernetes version](../concepts/release-channels-and-updates.md) for the Managed Service for Kubernetes cluster and node groups.
        * Managed Service for Kubernetes cluster CIDR.
        * Name of the Managed Service for Kubernetes cluster service account.
     1. Run the `terraform init` command in the directory with the configuration files. This command initializes the provider specified in the configuration files and enables you to use its resources and data sources.
     1. Validate your Terraform configuration files using this command:

        ```bash
        terraform validate
        ```

        Terraform will display any configuration errors detected in your files.
     1. Create the required infrastructure:

        1. Run this command to view the planned changes:
        
           ```bash
           terraform plan
           ```
        
           If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
        
        1. If everything looks correct, apply the changes:
           1. Run this command:
        
              ```bash
              terraform apply
              ```
        
           1. Confirm updating the resources.
           1. Wait for the operation to complete.

        All the required resources will be created in the specified folder. You can check resource availability and their settings in the [management console](https://console.yandex.cloud).

        {% note warning "Timeouts" %}
        
        The Terraform provider sets time limits for operations with Managed Service for Kubernetes cluster and node group:
        
        * Creating and editing a cluster: 30 minutes.
        * Creating and updating a node group: 60 minutes.
        * Deleting a node group: 20 minutes.
        
        Operations in excess of this time will be interrupted.
        
        {% cut "How do I modify these limits?" %}
        
        Add the `timeouts` sections (the `yandex_kubernetes_cluster` and `yandex_kubernetes_node_group` resources, respectively) to the cluster and node group description.
        
        Here is an example:
        
        ```hcl
        resource "yandex_kubernetes_node_group" "<node_group_name>" {
          ...
          timeouts {
            create = "1h30m"
            update = "1h30m"
            delete = "30m"
          }
        }
        ```
        
        {% endcut %}
        
        {% endnote %}

   {% endlist %}

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

1. [Create the `policy-test` namespace](kubernetes-cluster/kubernetes-cluster-namespace-create.md) in your Managed Service for Kubernetes cluster.

## Create an nginx service {#create-pod}

1. Create a pod with the nginx web server in the `policy-test` [namespace](../concepts/index.md#namespace). Use the [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) Kubernetes API object:

   ```bash
   kubectl create deployment --namespace=policy-test nginx --image=nginx
   ```

   Result:

   ```text
   deployment.apps/nginx created
   ```

1. Run the pod with nginx as a Kubernetes service:

   ```bash
   kubectl expose --namespace=policy-test deployment nginx --port=80
   ```

   Result:

   ```text
   service/nginx exposed
   ```

1. Make sure the nginx web server is available by creating a pod named `access`:

   ```bash
   kubectl run --namespace=policy-test access --rm -ti --image busybox /bin/sh
   ```

   A shell session will open on the `access` pod:

   ```text
   If you don't see a command prompt, try pressing enter.
   / #
   ```

1. Connect to the nginx web server via the session on the `access` pod:

   ```bash
   wget -q nginx -O -
   ```

   The nginx web server is available:

   ```html
   <!DOCTYPE html>
   <html>
   <head>
   ...
   <p><em>Thank you for using nginx.</em></p>
   </body>
   </html>
   ```

1. Exit the pod:

   ```bash
   / # exit
   ```

   The pod is deleted:

   ```text
   Session ended, resume using 'kubectl attach access -c access -i -t' command when the pod is running
   pod "access" deleted
   ```

## Isolate pods using network policies {#enable-isolation}

Isolate the `policy-test` namespace. As a result, the Calico network policy controller will prevent connections to pods in this namespace:

```yaml
kubectl create -f - <<EOF
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny
  namespace: policy-test
spec:
  podSelector:
    matchLabels: {}
EOF
```

Network policies are created:

```text
networkpolicy.networking.k8s.io/deny created
```

### Check whether isolation works {#test-isolation}

1. Network policies isolated the nginx web server. To check this, create a pod named `access`:

   ```bash
   kubectl run --namespace=policy-test access --rm -ti --image busybox /bin/sh
   ```

   A shell session will open on the `access` pod:

   ```text
   If you don't see a command prompt, try pressing enter.
   / #
   ```

1. Check if the `access` pod can access the nginx web server:

   ```bash
   wget -q --timeout=5 nginx -O -
   ```

   No connection is established:

   ```text
   wget: download timed out
   / #
   ```

1. Exit the pod:

   ```bash
   / # exit
   ```

   The pod is deleted:

   ```text
   Session ended, resume using 'kubectl attach access -c access -i -t' command when the pod is running
   pod "access" deleted
   ```

## Create network policies enabling service access {#create-policy}

Allow access to the nginx web server using network policies. These will only allow the `access` pod connections.
1. Create the `access-nginx` network policies:

   ```yaml
   kubectl create -f - <<EOF
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     name: access-nginx
     namespace: policy-test
   spec:
     podSelector:
       matchLabels:
         app: nginx
     policyTypes:
     - Ingress
     - Egress
     ingress:
       - from:
         - podSelector:
             matchLabels:
               run: access
     egress:
       - to:
         - podSelector:
             matchLabels:
               app: nginx
   EOF
   ```

   {% note info %}

   Network policies will allow traffic from pods with the `run: access` [Kubernetes label](../concepts/index.md#node-labels) to pods with the `app: nginx` Kubernetes label. Labels are automatically added by kubectl based on the resource name.

   {% endnote %}

   Network policies are created:

   ```text
   networkpolicy.networking.k8s.io/access-nginx created
   ```

1. Create a pod named `access`:

   ```bash
   kubectl run --namespace=policy-test access --rm -ti --image busybox /bin/sh
   ```

   A shell session will open on the `access` pod:

   ```text
   If you don't see a command prompt, try pressing enter.
   / #
   ```

1. Check if the `access` pod can access the nginx web server:

   ```bash
   wget -q --timeout=5 nginx -O -
   ```

   The connection is established:

   ```html
   <!DOCTYPE html>
   <html>
   <head>
   <title>Welcome to nginx!</title>
   ...
   ```

1. Exit the pod:

   ```bash
   / # exit
   ```

   The pod is deleted:

   ```text
   Session ended, resume using 'kubectl attach access -c access -i -t' command when the pod is running
   pod "access" deleted
   ```

### Check the network isolation for other pods {#check-isolation}

The `access-nginx` network policies you created allow connections for pods with the `run: access` Kubernetes label.
1. Create a pod without the `run: access` label:

   ```bash
   kubectl run --namespace=policy-test cant-access --rm -ti --image busybox /bin/sh
   ```

   A shell session will open on the `cant-access` pod:

   ```text
   If you don't see a command prompt, try pressing enter.
   / #
   ```

1. Check if the `cant-access` pod can access the nginx web server:

   ```bash
   wget -q --timeout=5 nginx -O -
   ```

   No connection is established:

   ```bash
   wget: download timed out
   / #
   ```

1. Exit the pod:

   ```bash
   / # exit
   ```

   The pod is deleted:

   ```text
   Session ended, resume using 'kubectl attach access -c access -i -t' command when the pod is running
   pod "cant-access" deleted
   ```

1. To delete the sample data, delete the namespace:

   ```bash
   kubectl delete ns policy-test
   ```

   Result:

   ```text
   namespace "policy-test" deleted
   ```

## Delete the resources you created {#clear-out}

Delete the resources you no longer need to avoid paying for them:

{% list tabs group=instructions %}

- Manually {#manual}

  1. [Delete the Managed Service for Kubernetes cluster](kubernetes-cluster/kubernetes-cluster-delete.md).
  1. [Delete](../../vpc/operations/address-delete.md) the public static IP address for your Managed Service for Kubernetes cluster if you reserved one.

- Terraform {#tf}

  1. In the terminal window, go to the directory containing the infrastructure plan.
  
      {% note warning %}
  
      Make sure the directory has no Terraform manifests with the resources you want to keep. Terraform deletes all resources that were created using the manifests in the current directory.
  
      {% endnote %}
  
  1. Delete resources:
  
      1. Run this command:
  
          ```bash
          terraform destroy
          ```
  
      1. Confirm deleting the resources and wait for the operation to complete.
  
      All the resources described in the Terraform manifests will be deleted.

{% endlist %}