[Yandex Cloud documentation](../../index.md) > [Tutorials](../index.md) > [Container infrastructure](index.md) > Managed Service for Kubernetes > Using Cloud Marketplace products > Logging settings for Application Load Balancer ingress controllers

# Configuring Yandex Application Load Balancer logging via an ingress controller

You can configure logging for [L7 load balancers](../../application-load-balancer/concepts/application-load-balancer.md) created with Application Load Balancer [ingress controllers](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) within a Managed Service for Kubernetes cluster.

{% note tip %}

We recommend using the new [Yandex Cloud Gwin](../../application-load-balancer/tools/gwin/index.md) controller instead of an ALB Ingress controller and Gateway API.

{% endnote %}

This tutorial explains how to create three L7 load balancers with different logging settings:

* Save logs to the [default log group](../../logging/concepts/log-group.md).
* Save logs to a custom log group.
* Save no logs.

To configure L7 load balancers:

1. [Create a test application](#install-app).
1. [Create Ingress resources](#create-ingress).
1. [Specify the settings for the Ingress resource groups](#configure-group).
1. [Check the result](#check-result).

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


## Required paid resources {#paid-resources}

The support cost for this solution includes:

* Fee for a DNS zone and DNS requests (see [Cloud DNS pricing](../../dns/pricing.md)).
* Fee for using the master and outgoing traffic in a Managed Service for Kubernetes cluster (see [Managed Service for Kubernetes pricing](../../managed-kubernetes/pricing.md)).
* Fee for using computing resources, OS, and storage in cluster nodes (VMs) (see [Compute Cloud pricing](../../compute/pricing.md)).
* Fee for using computing resources of each L7 load balancer (see [Application Load Balancer pricing](../../application-load-balancer/pricing.md)).
* Fee for public IP addresses for cluster nodes and L7 load balancers (see [Virtual Private Cloud pricing](../../vpc/pricing.md#prices-public-ip)).
* Cloud Logging fee for data logging and storage (see [Cloud Logging pricing](../../logging/pricing.md)).


## Getting started {#before-begin}

### Set up your infrastructure {#deploy-infrastructure}

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

The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

{% list tabs group=instructions %}

- Manually {#manual}

    1. Create the following [service accounts](../../iam/operations/sa/create.md) for the Managed Service for Kubernetes cluster:

        * Service account for resources with the `k8s.clusters.agent` and `vpc.publicAdmin` [roles](../../managed-kubernetes/security/index.md#yc-api) for the [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) to host the new [Managed Service for Kubernetes cluster](../../managed-kubernetes/concepts/index.md#kubernetes-cluster).
        * Service account for nodes with the [container-registry.images.puller](../../container-registry/security/index.md#container-registry-images-puller) role for the folder with the Docker image [registry](../../container-registry/concepts/registry.md). The nodes will use this account to pull the required Docker images from the registry.
        * Service account for the Application Load Balancer ingress controller with the following roles:

            * [alb.editor](../../application-load-balancer/security/index.md#alb-editor): To create the required resources.
            * [vpc.publicAdmin](../../vpc/security/index.md#vpc-public-admin): To manage [external connectivity](../../vpc/security/index.md#roles-list).
            * [certificate-manager.certificates.downloader](../../certificate-manager/security/index.md#certificate-manager-certificates-downloader): To use certificates registered in [Yandex Certificate Manager](../../certificate-manager/index.md).
            * [compute.viewer](../../compute/security/index.md#compute-viewer): To use Managed Service for Kubernetes cluster nodes in the load balancer’s [target groups](../../application-load-balancer/concepts/target-group.md).

        You can use the same service account for all operations.

    1. [Create an authorized key](../../iam/operations/authentication/manage-authorized-keys.md#create-authorized-key) for the ingress controller's service account in JSON format and save it to the `key.json` file:

        ```bash
        yc iam key create \
           --service-account-name <name_of_service_account_for_ingress_controller> \
           --output key.json
        ```

        You need the key data to [install](#install-alb-ingress-controller) the ALB ingress controller.

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

        [Configure](../../application-load-balancer/tools/k8s-ingress-controller/security-groups.md) the security groups required for Application Load Balancer as well.

        {% 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](../../managed-kubernetes/operations/kubernetes-cluster/kubernetes-cluster-create.md#kubernetes-cluster-create). Use these settings:

        * Specify the previously created service account for resources as well as security groups.
        * For Yandex Cloud internal network usage, your cluster does not need a public IP address. To enable internet access to your cluster, assign it a public IP address.

    1. [Create a node group](../../managed-kubernetes/operations/node-group/node-group-create.md). Use these settings:

        * Specify the previously created service account for nodes as well as security groups.
        * To enable internet access for your node group (e.g., for Docker image pulls), assign it a public IP address.

    1. [Create a custom Cloud Logging log group](../../logging/operations/create-group.md).

- Terraform {#tf}

    1. If you do not have Terraform yet, [install it](../infrastructure-management/terraform-quickstart.md#install-terraform).
    1. [Get the authentication credentials](../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](../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](../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-and-registry-for-alb.tf](https://github.com/yandex-cloud-examples/yc-mk8s-ingress-controller-logging/blob/main/k8s-and-registry-for-alb.tf) configuration file to the same working directory.

        This file describes:

        * [Network](../../vpc/concepts/network.md#network).
        * [Subnet](../../vpc/concepts/network.md#subnet).
        * Managed Service for Kubernetes cluster.
        * [Security groups](../../vpc/concepts/security-groups.md) which contain [rules](../../managed-kubernetes/operations/connect/security-groups.md) required for the Managed Service for Kubernetes cluster and its node groups.

            [Some rules](../../application-load-balancer/tools/k8s-ingress-controller/security-groups.md) are required for Application Load Balancer to work correctly.

            {% note warning %}
            
            The configuration of security groups determines performance and availability of the cluster and the services and applications running in it.
            
            {% endnote %}

        * [Service account](../../iam/concepts/users/service-accounts.md) for Managed Service for Kubernetes resources and nodes.
        * Service account for the Application Load Balancer ingress controller.
        * [Custom Cloud Logging log group](../../logging/concepts/log-group.md).
        * [Authorized key](../../iam/concepts/authorization/key.md) for the service account of the ingress controller.
        * Creating a local `key.json` file with the authorized key data. You need the key data to [install](#install-alb-ingress-controller) the ALB ingress controller.

    1. Specify the following in the `k8s-and-registry-for-alb.tf` file:

        * [Folder ID](../../resource-manager/operations/folder/get-id.md).
        * [Kubernetes version](../../managed-kubernetes/concepts/release-channels-and-updates.md) for the Managed Service for Kubernetes cluster and node groups.
        * Name of the service account for Kubernetes resources and nodes.
        * Name of the service account for the Application Load Balancer ingress controller.
        * Name of the custom Cloud Logging log group.

    1. Make sure the Terraform configuration files are correct using this command:

        ```bash
        terraform validate
        ```

        Terraform will show any errors found in your configuration 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).

{% endlist %}

### Get ready to use the Managed Service for Kubernetes cluster {#prepare-k8s-cluster}

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

   If your cluster has no public IP address assigned and `kubectl` is configured via the cluster's private IP address, run `kubectl` commands on a Yandex Cloud VM residing in the same network as the cluster.

1. [Install Helm](https://helm.sh/docs/intro/install).

### Register a domain zone {#register-domain}

[Register a public domain zone and delegate your domain](../../dns/operations/zone-create-public.md).

### Install the Application Load Balancer ingress controller {#install-alb-ingress-controller}

Install the [ALB ingress controller](https://yandex.cloud/en/marketplace/products/yc/alb-ingress-controller) by following [this guide](../../managed-kubernetes/operations/applications/alb-ingress-controller.md). During the installation, use `key.json` you created when [setting up your infrastructure](#deploy-infrastructure).

## Create a test application {#install-app}

Create the [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/), [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) with NGINX, and [Service](https://kubernetes.io/docs/concepts/services-networking/service/) objects for the application.

1. Create the `app.yaml` file:

    {% cut "app.yaml" %}

    ```yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: alb-demo-1
    data:
      nginx.conf: |
        worker_processes auto;
        events {
        }
        http {
          server {
            listen 80 ;
            location = /_healthz {
              add_header Content-Type text/plain;
              return 200 'ok';
            }
            location / {
              add_header Content-Type text/plain;
              return 200 'Index';
            }
            location = /app1 {
              add_header Content-Type text/plain;
              return 200 'This is APP#1';
            }
          }
        }
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: alb-demo-1
      labels:
        app: alb-demo-1
        version: v1
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: alb-demo-1
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 0
      template:
        metadata:
          labels:
            app: alb-demo-1
            version: v1
        spec:
          terminationGracePeriodSeconds: 5
          volumes:
            - name: alb-demo-1
              configMap:
                name: alb-demo-1
          containers:
            - name: alb-demo-1
              image: nginx:latest
              ports:
                - name: http
                  containerPort: 80
              livenessProbe:
                httpGet:
                  path: /_healthz
                  port: 80
                initialDelaySeconds: 3
                timeoutSeconds: 2
                failureThreshold: 2
              volumeMounts:
                - name: alb-demo-1
                  mountPath: /etc/nginx
                  readOnly: true
              resources:
                limits:
                  cpu: 250m
                  memory: 128Mi
                requests:
                  cpu: 100m
                  memory: 64Mi
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: alb-demo-1
    spec:
      selector:
        app: alb-demo-1
      type: NodePort
      ports:
        - name: http
          port: 80
          targetPort: 80
          protocol: TCP
          nodePort: 30081
    ```

    {% endcut %}

1. Create an app:

    ```bash
    kubectl apply -f app.yaml
    ```

    Result:

    ```text
    configmap/alb-demo-1 created
    deployment.apps/alb-demo-1 created
    service/alb-demo-1 created
    ```

## Create Ingress resources {#create-ingress}

Create three [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) resources that the Application Load Balancer ingress controller will use to deploy three load balancers with the required listeners and HTTP routers.

1. Create a file named `ingress.yaml` with the load balancer settings and domain name:

    ```yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: logs-demo-nondefault
      annotations:
        ingress.alb.yc.io/group-name: non-default
        ingress.alb.yc.io/subnets: <list_of_subnet_IDs>
        ingress.alb.yc.io/security-groups: <list_of_security_group_IDs>
        ingress.alb.yc.io/group-settings-name: non-default-settings
        ingress.alb.yc.io/external-ipv4-address: auto
    spec:
      rules:
        - host: <domain_name>
          http:
            paths:
              - pathType: Prefix
                path: "/"
                backend:
                  service:
                    name: alb-demo-1
                    port: 
                      name: http
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: logs-demo-disabled
      annotations:
        ingress.alb.yc.io/group-name: logs-disabled
        ingress.alb.yc.io/subnets: <list_of_subnet_IDs>
        ingress.alb.yc.io/security-groups: <list_of_security_group_IDs>
        ingress.alb.yc.io/group-settings-name: logs-disabled-settings
        ingress.alb.yc.io/external-ipv4-address: auto
    spec:
      rules:
        - host: <domain_name>
          http:
            paths:
              - pathType: Prefix
                path: "/"
                backend:
                  service:
                    name: alb-demo-1
                    port:
                      name: http
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: logs-demo-default
      annotations:
        ingress.alb.yc.io/group-name: default
        ingress.alb.yc.io/subnets: <list_of_subnet_IDs>
        ingress.alb.yc.io/security-groups: <list_of_security_group_IDs>
        ingress.alb.yc.io/external-ipv4-address: auto
    spec:
      rules:
        - host: <domain_name>
          http:
            paths:
              - pathType: Prefix
                path: "/"
                backend:
                  service:
                    name: alb-demo-1
                    port:
                      name: http
    ```

    Where:

    * `ingress.alb.yc.io/group-name`: Group name. Ingress resources are grouped so that a separate Application Load Balancer serves each group.
    * `ingress.alb.yc.io/subnets`: One or more [subnets](../../vpc/concepts/network.md#subnet) to host the load balancer.
    * `ingress.alb.yc.io/security-groups`: One or more [security groups](../../application-load-balancer/concepts/application-load-balancer.md#security-groups) for the load balancer. If you skip this parameter, the default security group will be used.
    * `ingress.alb.yc.io/external-ipv4-address`: Public access to the load balancer from the internet. Enter the [IP address you got earlier](../../vpc/operations/get-static-ip.md) or set `auto` to get a new IP address automatically.

       If you set `auto`, deleting the load balancer from the [cloud](../../resource-manager/concepts/resources-hierarchy.md#cloud) removes its [IP address](../../vpc/concepts/address.md). To avoid this, use a reserved IP address.

    * `ingress.alb.yc.io/group-settings-name`: Name for the Ingress resource group settings to describe in the `IngressGroupSettings` optional resource.

    Optionally, specify the additional controller settings:

    {% note info %}
    
    The settings listed below will only apply to the [virtual hosts](../../application-load-balancer/tools/k8s-ingress-controller/principles.md#mapping) of the Ingress resource in which the corresponding annotations are configured.
    
    They will not apply to the virtual hosts of the group's other Ingress resources.
    
    {% endnote %}

    * `ingress.alb.yc.io/internal-ipv4-address`: Provide internal access to the load balancer. Enter the internal IP address or use `auto` to get the IP address automatically.

        {% note info %}

        You can only use one type of access to the load balancer at a time: `ingress.alb.yc.io/external-ipv4-address` or `ingress.alb.yc.io/internal-ipv4-address`.

        {% endnote %}

    * `ingress.alb.yc.io/internal-alb-subnet`: Subnet to host the load balancer. This parameter is required if you select `ingress.alb.yc.io/internal-ipv4-address`.
    * `ingress.alb.yc.io/protocol`: Protocol for connections between the load balancer and backends:

        * `http`: HTTP/1.1. This is a default value.
        * `http2`: HTTP/2.
        * `grpc`: gRPC.

    * `ingress.alb.yc.io/transport-security`: Encryption protocol for connections between the load balancer and backends.

        {% note warning %}

        For [ALB Ingress Controller](https://yandex.cloud/en/marketplace/products/yc/alb-ingress-controller) 0.2.0 and later, you can only use this annotation in the [Service](../../application-load-balancer/k8s-ref/service-for-ingress.md#metadata) object.

        Annotations specified in `Ingress` resources sharing a single service with the same backend group settings apply correctly. However, this feature is deprecated and will be discontinued.

        {% endnote %}

        The acceptable value is `tls`: TLS without certificate validation.

        If this annotation is not specified, the load balancer will connect to the backends without encryption.

    * `ingress.alb.yc.io/prefix-rewrite`: Replace the path with the specified value.
    * `ingress.alb.yc.io/upgrade-types`: Valid values of the `Upgrade` HTTP header, e.g., `websocket`.
    * `ingress.alb.yc.io/request-timeout`: Maximum connection request timeout.
    * `ingress.alb.yc.io/idle-timeout`: Maximum connection idle timeout.

        Make sure to provide the `request-timeout` and `idle-timeout` values with units of measurement, e.g., `300ms` or `1.5h`. Acceptable units of measurement include:
        * `ns`, nanoseconds
        * `us`, microseconds
        * `ms`, milliseconds
        * `s`, seconds
        * `m`, minutes
        * `h`, hours

    For more information about the Ingress resource settings, see [Ingress resource fields and annotations](../../managed-kubernetes/alb-ref/ingress.md).

1. Create Ingress resources:

    ```bash
    kubectl apply -f ingress.yaml
    ```

    Result:

    ```text
    ingress.networking.k8s.io/logs-demo-nondefault created
    ingress.networking.k8s.io/logs-demo-disabled created
    ingress.networking.k8s.io/logs-demo-default created
    ```

    The system will automatically deploy three [L7 load balancers](../../application-load-balancer/concepts/application-load-balancer.md) based on the Ingress resource configurations.

## Specify the settings for the Ingress resource groups {#configure-group}

Create the `IngressGroupSettings` resource with these logging settings for the Ingress resource groups:

* `non-default-settings`: Logging to the [previously](#deploy-infrastructure) created custom log group with defined rules.
* `logs-disabled-settings`: No logging.

If you want to have logs saved to the default log group, skip these settings.

1. Create the `settings.yaml` file with the log group ID:

    ```yaml
    apiVersion: alb.yc.io/v1alpha1
    kind: IngressGroupSettings
    metadata:
      name: non-default-settings
    logOptions:
      logGroupID: <custom_log_group_ID>
      discardRules:
        - discardPercent: 50
          grpcCodes:
            - OK
            - CANCELLED
            - UNKNOWN
        - discardPercent: 67
          httpCodeIntervals:
            - HTTP_1XX
        - discardPercent: 20
          httpCodes:
            - 200
            - 404
    ---
    apiVersion: alb.yc.io/v1alpha1
    kind: IngressGroupSettings
    metadata:
      name: logs-disabled-settings
    logOptions:
      disable: true
    ```

1. Create the resources:

    ```bash
    kubectl apply -f settings.yaml
    ```

    Result:

    ```text
    ingressgroupsettings.alb.yc.io/non-default-settings created
    ingressgroupsettings.alb.yc.io/logs-disabled-settings created
    ```

The settings from those resources will apply to the Ingress resource groups in line with the `ingress.alb.yc.io/group-settings-name` annotations [specified for the Ingress resources](#create-ingress).

## Check the result {#check-result}

[Get the log group IDs](../../application-load-balancer/operations/application-load-balancer-get-log-group-id.md) for the new L7 load balancers and make sure they match the settings in `settings.yaml`:

* For one of the load balancers, select the custom log group you created with defined rules.
* Use the default log group for another.
* For the third load balancer, disable logging.

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

Some resources are not free of charge. 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](../../managed-kubernetes/operations/kubernetes-cluster/kubernetes-cluster-delete.md).
    1. [Delete](../../vpc/operations/address-delete.md) the cluster public static IP address if you reserved one.
    1. [Delete the service accounts](../../iam/operations/sa/delete.md).
    1. [Delete the log group](../../logging/operations/delete-group.md).

- 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 %}