<a id="installation-in-yc"></a>

# Установка и настройка для Яндекс.Облака

В этом разделе описана установка и настройка ANIC в качестве Ingress для Яндекс.Облака.

## Настройка локальной рабочей среды для работы с Kubernetes и Яндекс.Облаком

Пример для Ubuntu 24/04.

1. Скачайте и установите CLI (YC) для управления ресурсами в Яндекс.Облаке:
   ```console
   $ curl -sSL https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash
   $ yc init
   ```

   Запустится процесс настройки CLI, где потребуется ввести токен для доступа в Яндекс.Облако.
   Токен можно получить по ссылке [https://oauth.yandex.ru/verification_code](https://oauth.yandex.ru/verification_code).
2. Добавьте параметры подключения к Kubernetes-кластеру (например, `otus`) в файл `~/.kube/config` и подключитесь к кластеру:
   ```console
   $ yc managed-kubernetes cluster get-credentials otus --external
   ```
3. Проверьте конфигурацию кластера, ноды и доступные сервисы:
   ```console
   $ kubectl config view
   $ kubectl get nodes
   $ kubectl get svc
   ```

## Получение доступа к образу ANIC

1. Создайте Docker-секрет.

   Выполните авторизацию в Docker Registry, чтобы получить доступ к образу:
   ```console
   $ docker login -u=<login> -p=<password> anic.docker.angie.software
   ```

   После успешной авторизации информация о доступе будет сохранена в файле `~/.docker/config.json`.
2. Создайте секрет для Kubernetes, используя файл Docker-конфигурации:
   ```console
   $ kubectl create secret generic regcred \
         --from-file=.dockerconfigjson=$HOME/.docker/config.json \
         --type=kubernetes.io/dockerconfigjson
   ```

   Секрет `regcred` будет использоваться для доступа к приватным образам в Kubernetes.

## Получение и настройка Helm-чартов

1. Склонируйте Helm-чарты из репозитория:
   ```none
   $ git clone https://git.angie.software/web-server/anic-helm-charts.git
   $ cd anic-helm-charts/anic/
   ```
2. Отредактируйте `values.yaml`. Укажите имя созданного секрета
   для доступа к образам и включите поддержку менеджера сертификатов:
   ```yaml
   ...
   imagePullSecretName: "regcred"
   ...
   enableCertManager: true
   ...
   ```
3. Соберите и установите чарт:
   ```none
   $ helm install anic .
   ```
4. Обновите чарт:
   ```none
   $ helm upgrade anic .
   ```

## Запуск менеджера сертификатов

1. Установите `cert-manager` для управления сертификатами.
   Работа тестировалась на примере версии 1.12.1:
   ```console
   $ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.1/cert-manager.yaml
   ```
2. Убедитесь, что три пода `cert-manager` находятся в состоянии `running` с готовностью 1/1:
   ```console
   $ kubectl get pods -n cert-manager --watch
   ```
3. Создайте объект ClusterIssuer для выпуска сертификатов:

   ### http01-clusterissuer.yaml

   ```yaml
   apiVersion: cert-manager.io/v1
   kind: ClusterIssuer
   metadata:
     name: http01-clusterissuer
   spec:
     acme:
       server: https://acme-v02.api.letsencrypt.org/directory
       email: test@test.ru
       privateKeySecretRef:
         name: http01-clusterissuer-secret
       solvers:
       - http01:
           ingress:
             class: angie
   ```

   В этом примере cert-manager настроен для автоматической выдачи сертификатов от Let's Encrypt с помощью HTTP-01 проверки.
4. Примените манифест для объекта ClusterIssuer:
   ```console
   $ kubectl apply -f http01-clusterissuer.yaml
   ```

После выполнения всех шагов, у вас будет настроен доступ к образу ANIC, чарт развернут в Kubernetes, а cert-manager будет управлять сертификатами.

## Развертывание ANIC и тестового приложения в Kubernetes

1. Настройте домен и поиск внешнего IP-адреса. Создайте Ingress-ресурс, сервис и деплоймент для тестового приложения.

   Замените доменное имя `otus-kube.mtdlb.ru` на ваш действующий домен.
   Внешний IP-адрес кластера можно найти в Яндекс.Облаке в разделе `Managed Service for Kubernetes` → `Кластеры` → `otus` → `Сеть`.
   Этот IP-адрес будет использоваться для привязки домена.

   ### app-angie.yaml

   ```yaml
   apiVersion: networking.k8s.io/v1
   kind: Ingress
   metadata:
     name: minimal-ingress
     annotations:
       cert-manager.io/cluster-issuer: "http01-clusterissuer"
       acme.cert-manager.io/http01-edit-in-place: "true"
   spec:
     ingressClassName: angie
     tls:
       - hosts:
         - otus-kube.mtdlb.ru
         secretName: domain-name-secret
     rules:
       - host: otus-kube.mtdlb.ru
         http:
           paths:
           - path: /
             pathType: Prefix
             backend:
               service:
                 name: app
                 port:
                   number: 80
   ---
   apiVersion: v1
   kind: Service
   metadata:
     name: app
   spec:
     selector:
       app: app
     ports:
       - protocol: TCP
         port: 80
         targetPort: 80
   ---
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: app-deployment
     labels:
       app: app
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: app
     template:
       metadata:
         labels:
           app: app
       spec:
         containers:
         - name: app
           image: angie:latest
           ports:
           - containerPort: 80
   ```
2. Запустите приложение:
   ```console
   $ kubectl apply -f app-angie.yaml
   ```
3. Проверьте статус SSL-сертификата и его секрет в Kubernetes:
   ```console
   $ kubectl describe certificate domain-name-secret
   $ kubectl describe secret domain-name-secret
   ```

## Проверка работы

Откройте в браузере домен, который вы указали в конфигурации (например, [https://otus-kube.mtdlb.ru](https://otus-kube.mtdlb.ru)).

Если возникают проблемы, можно проверить логи подов:

```console
$ kubectl logs -l app=app
```

Также можно посмотреть конфигурацию ANIC (подставьте в `anic-64ff957589-jlg7s` имя пода с ANIC в вашем кластере):

```console
$ kubectl exec anic-64ff957589-jlg7s -- angie -T
```

## Удаление развернутого приложения

Если нужно удалить все созданные ресурсы, выполните:

```console
$ kubectl delete -f app-angie.yaml
```

## Проксирование TCP-трафика через ANIC в Kubernetes

Ниже приведен пример настройки проксирования TCP-трафика для доступа к MySQL.

Предварительно необходимо включить `globalConfiguration` в `values.yaml` чарта,
за счет него можно определить `listener`.

1. Установите чарт с выключенным параметром `globalConfiguration`:
   ```yaml
   globalConfiguration:
     ## Creates the GlobalConfiguration custom resource. Requires controller.enableCustomResources.
     create: false
   ```
2. Выполните команду:
   ```console
   $ helm upgrade anic .
   ```
3. Теперь установите чарт с включенным параметром `globalConfiguration` и добавьте TCP-прослушиватель:
   ```yaml
   globalConfiguration:
     ## Creates the GlobalConfiguration custom resource. Requires controller.enableCustomResources.
     create: true

     ## The spec of the GlobalConfiguration for defining the global configuration parameters of the Ingress Controller.
     spec:
       listeners:
       # - name: dns-udp
       #   port: 5353
       #   protocol: UDP
       - name: mysql-tcp
         port: 13306
         protocol: TCP
   ```
4. Обновите чарт:
   ```console
   $ helm upgrade anic .
   ```

   Теперь ANIC будет слушать TCP-порт 13306 для подключения к MySQL.
5. Создайте секрет с паролем root:

   ### mysql-seceret.yaml

   ```yaml
   apiVersion: v1
    kind: Secret
    metadata:
      name: mysql-secret
    type: kubernetes.io/basic-auth
    stringData:
      password: kljJ218q23cujvdshi
   ```
6. Создайте  постоянное хранилище (volume) для MySQL:

   ### mysql-storage.yaml

   ```yaml
   apiVersion: v1
   kind: PersistentVolume
   metadata:
     name: mysql-pv-volume
     labels:
       type: local
   spec:
     storageClassName: manual
     capacity:
       storage: 10Gi
     accessModes:
       - ReadWriteOnce
     hostPath:
       path: "/mnt/data"
   ---
   apiVersion: v1
   kind: PersistentVolumeClaim
   metadata:
     name: mysql-pv-claim
   spec:
     storageClassName: manual
     accessModes:
       - ReadWriteOnce
     resources:
       requests:
         storage: 10Gi
   ```
7. Разверните сам MySQL:

   ### mysql-deployment.yaml

   ```yaml
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: mysql
   spec:
     selector:
       matchLabels:
         app: mysql
     strategy:
       type: Recreate
     template:
       metadata:
         labels:
           app: mysql
       spec:
         containers:
         - image: mysql:8.0
           name: mysql
           env:
           - name: MYSQL_ROOT_PASSWORD
             valueFrom:
               secretKeyRef:
                 name: mysql-secret
                 key: password
           ports:
           - containerPort: 3306
             name: mysql
           volumeMounts:
           - name: mysql-persistent-storage
             mountPath: /var/lib/mysql
         volumes:
         - name: mysql-persistent-storage
           persistentVolumeClaim:
             claimName: mysql-pv-claim
   ---
   apiVersion: v1
   kind: Service
   metadata:
     name: mysql
   spec:
     ports:
     - port: 3306
     selector:
       app: mysql
   ```
8. Создайте сервис для MySQL:

   ### mysql-service.yaml

   ```yaml
   apiVersion: v1
   kind: Service
   metadata:
     name: mysql-ext
   spec:
     type: LoadBalancer
     ports:
     - port: 13306
       name: mysql
       targetPort: 13306
     # Kubernetes-метки селектора, использованные в шаблоне подов при создании объекта Deployment.
     selector:
       app: mysql-tcp
   ```
9. Настройте ANIC для MySQL:

   ### anic-mysql.yaml

   ```yaml
   apiVersion: k8s.angie.software/v1alpha1
   kind: TransportServer
   metadata:
     name: mysql-tcp
   spec:
     listener:
       name: mysql-tcp
       protocol: TCP
     upstreams:
     - name: mysql
       service: mysql
       port: 3306
     action:
       pass: mysql
   ```
10. Примените настройки, чтобы развернуть сервис:
    ```console
    $ kubectl apply -f mysql-secret.yaml
    $ kubectl apply -f mysql-storage.yaml
    $ kubectl apply -f mysql-deployment.yaml
    $ kubectl apply -f mysql-service.yaml
    $ kubectl apply -f anic-mysql.yaml
    ```

    Теперь трафик на порт 13306 будет перенаправляться в MySQL.
11. Проверьте статус:
    ```console
    $ kubectl get svc           # Список сервисов
    $ kubectl describe gc       # Описание GlobalConfiguration
    $ kubectl describe ts mysql-tcp   # Описание TCP-listener
    $ kubectl describe service anic  # Информация об ANIC
    ```
