<a id="migration-to-anic"></a>

# Миграция с Ingress-NGINX Controller на ANIC

Для миграции ANIC должен быть [установлен](https://angie.software//anic/docs/installation/installation-with-helm.md#installation-with-helm) на том же хосте, где уже работает Ingress-NGINX Controller.

## Перенос конфигурации

1. Настройте [ConfigMap](https://angie.software//anic/docs/configuration/config.md#anic-config) для ANIC, добавив общие параметры для всех Ingress.
   Эти параметры будут использоваться по умолчанию для всех Ingress, если конкретный манифест их не переопределяет.
2. В манифестах для сервисов измените аннотации Ingress-NGINX Controller на соответствующие аннотации ANIC, где это необходимо.

   Для аннотаций, которые не поддерживаются в ANIC, используйте другие варианты настройки конфигурации (см. примеры ниже).
3. По очереди перенесите манифесты для сервисов, проверяя, что каждый манифест работает корректно.

#### NOTE
Не рекомендуется изменять поле `spec` в ресурсе Ingress. Реализации Ingress-NGINX Controller и ANIC отличаются, что может привести к проблемам совместимости.

## Соответствия для аннотаций

В таблице ниже приведены аннотации Ingress-NGINX Controller с эквивалентными аннотациями ANIC.

| Ingress-NGINX Controller                            | ANIC                                   |
|-----------------------------------------------------|----------------------------------------|
| `nginx.ingress.kubernetes.io/configuration-snippet` | `angie.software/location-snippets`     |
| `nginx.ingress.kubernetes.io/load-balance`          | `angie.software/lb-method`             |
| `nginx.ingress.kubernetes.io/proxy-buffering`       | `angie.software/proxy-buffering`       |
| `nginx.ingress.kubernetes.io/proxy-buffers-number`  | `angie.software/proxy-buffers`         |
| `nginx.ingress.kubernetes.io/proxy-buffer-size`     | `angie.software/proxy-buffer-size`     |
| `nginx.ingress.kubernetes.io/proxy-connect-timeout` | `angie.software/proxy-connect-timeout` |
| `nginx.ingress.kubernetes.io/proxy-read-timeout`    | `angie.software/proxy-read-timeout`    |
| `nginx.ingress.kubernetes.io/proxy-send-timeout`    | `angie.software/proxy-send-timeout`    |
| `nginx.ingress.kubernetes.io/rewrite-target`        | `angie.software/rewrites`              |
| `nginx.ingress.kubernetes.io/server-snippet`        | `angie.software/server-snippets`       |
| `nginx.ingress.kubernetes.io/ssl-redirect`          | `ingress.kubernetes.io/ssl-redirect`   |

Полный список аннотаций ANIC см. в разделе [Расширенная конфигурация с помощью аннотаций](https://angie.software//anic/docs/configuration/annotations.md#annotations).

## Глобальная конфигурация с помощью ConfigMap

В таблице ниже приведено ключи ConfigMap в Ingress-NGINX Controller и их эквиваленты в ANIC.

| Ingress-NGINX Controller         | ANIC                            |
|----------------------------------|---------------------------------|
| `disable-access-log`             | `access-log-off`                |
| `hsts`                           | `hsts`                          |
| `hsts-include-subdomains`        | `hsts-include-subdomains`       |
| `hsts-max-age`                   | `hsts-max-age`                  |
| `http-snippet`                   | `http-snippets`                 |
| `keep-alive`                     | `keepalive-timeout`             |
| `keep-alive-requests`            | `keepalive-requests`            |
| `load-balance`                   | `lb-method`                     |
| `location-snippet`               | `location-snippets`             |
| `log-format-escape-json`         | `log-format-escaping: "json"`   |
| `log-format-stream`              | `stream-log-format`             |
| `log-format-upstream`            | `log-format`                    |
| `main-snippet`                   | `main-snippets`                 |
| `max-worker-connections`         | `worker-connections`            |
| `max-worker-open-files`          | `worker-rlimit-nofile`          |
| `proxy-body-size`                | `client-max-body-size`          |
| `proxy-buffering`                | `proxy-buffering`               |
| `proxy-buffers-number`           | `proxy-buffers: number size`    |
| `proxy-buffer-size`              | `proxy-buffers: number size`    |
| `proxy-connect-timeout`          | `proxy-connect-timeout`         |
| `proxy-read-timeout`             | `proxy-read-timeout`            |
| `proxy-send-timeout`             | `proxy-send-timeout`            |
| `server-name-hash-bucket-size`   | `server-names-hash-bucket-size` |
| `proxy-headers-hash-max-size`    | `server-names-hash-max-size`    |
| `server-snippet`                 | `server-snippets`               |
| `server-tokens`                  | `server-tokens`                 |
| `upstream-keepalive-connections` | `keepalive`                     |
| `use-http2`                      | `http2`                         |
| `use-proxy-protocol`             | `proxy-protocol`                |
| `variables-hash-bucket-size`     | `variables-hash-bucket-size`    |
| `worker-cpu-affinity`            | `worker-cpu-affinity`           |
| `worker-processes`               | `worker-processes`              |
| `worker-shutdown-timeout`        | `worker-shutdown-timeout`       |

## Примеры

### Настройка терминации SSL и маршрутизации на основе HTTP-путей

Ingress-NGINX Controller:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-test
spec:
  tls:
    - hosts:
      - foo.bar.com
      secretName: tls-secret
  rules:
    - host: foo.bar.com
      http:
        paths:
        - path: /login
          backend:
            serviceName: login-svc
            servicePort: 80
        - path: /billing
            serviceName: billing-svc
            servicePort: 80
```

ANIC:

```yaml
apiVersion: networking.k8s.io/v1
kind: VirtualServer
metadata:
  name: anic-test
spec:
  host: foo.bar.com
  tls:
    secret: tls-secret
  upstreams:
    - name: login
      service: login-svc
      port: 80
    - name: billing
      service: billing-svc
      port: 80
  routes:
  - path: /login
    action:
      pass: login
  - path: /billing
    action:
      pass: billing
```

### Настройка балансировки нагрузки TCP/UDP и TLS Passthrough

ANIC предоставляет доступ к TCP- и UDP-сервисам с помощью ресурсов TransportServer и GlobalConfiguration.
Ingress-NGINX Controller использует для этой цели ConfigMap.

### Канареечные развертывания

Канареечные и сине-зеленые развертывания (сanary deployment и blue-green deployment) позволяют
внедрять изменения в код в продакшн-среде, не прерывая работу пользователей.
ANIC выполняет развертывания на уровне передачи данных: чтобы перейти с Ingress-NGINX Controller на ANIC,
необходимо сопоставить аннотации Ingress-NGINX Controller с ресурсами VirtualServer и VirtualServerRoute в ANIC.

Ingress-NGINX Controller обрабатывает канареечные аннотации в следующем порядке:

1. `nginx.ingress.kubernetes.io/canary-by-header`
2. `nginx.ingress.kubernetes.io/canary-by-cookie`
3. `nginx.ingress.kubernetes.io/canary-by-weight`

#### NOTE
Чтобы канареечные аннотации интерпретировались в ANIC аналогично, они должны располагаться в манифесте VirtualServer или VirtualServerRoute в том же порядке.

### nginx.ingress.kubernetes.io/canary-by-header

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "httpHeader"
```

ANIC:

```yaml
matches:
- conditions:
- header: httpHeader
value: never
action:
pass: echo
- header: httpHeader
value: always
action:
pass: echo-canary
action:
pass: echo
```

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "httpHeader"
nginx.ingress.kubernetes.io/canary-by-header-value: "my-value"
```

ANIC:

```yaml
matches:
- conditions:
  - header: httpHeader
      value: my-value
  action:
    pass: echo-canary
action:
  pass: echo
```

### nginx.ingress.kubernetes.io/canary-by-cookie

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-cookie: "cookieName"
```

ANIC:

```yaml
matches:
- conditions:
  - cookie: cookieName
      value: never
  action:
    pass: echo
  - cookie: cookieName
      value: always
  action:
    pass: echo-canary
action:
  pass: echo
```

### Управление трафиком

Аннотации Ingress-NGINX Controller, для которых пока нет соответствующих полей в ресурсах ANIC, необходимо обрабатывать с помощью фрагментов (сниппетов).

#### NOTE
Для работы в чарте необходимо установить `controller.enableSnippets` в `true`.

В примерах ниже аннотации Ingress-NGINX Controller сопоставлены с ресурсами VirtualServer
и VirtualServerRoute в ANIC.

### custom-http-errors

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/custom-http-errors: "code"
nginx.ingress.kubernetes.io/default-backend: "default-svc"
```

ANIC:

```yaml
errorPages:
- codes: [code]
    redirect:
      code: 301
      url: default-svc
```

### limit-connections

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/limit-connections: "number"
```

ANIC:

```yaml
http-snippets: |
    limit_conn_zone $binary_remote_addr zone=zone_name:size;
routes:
- path: /path
    location-snippets: |
      limit_conn zone_name number;
```

### limit-rate

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/limit-rate: "number"
nginx.ingress.kubernetes.io/limit-rate-after: "number"
```

ANIC:

```yaml
location-snippets: |
    limit_rate number;

    limit_rate_after number;
```

### limit-rpm

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/limit-rpm: "number"
nginx.ingress.kubernetes.io/limit-burst-multiplier: "multiplier"
```

ANIC:

```yaml
rateLimit:
    rate: numberr/m

    burst: number * multiplier
    key: ${binary_remote_addr}
    zoneSize: size
```

### limit-rps

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/limit-rps: "number"
nginx.ingress.kubernetes.io/limit-burst-multiplier: "multiplier"
```

ANIC:

```yaml
rateLimit:
    rate: numberr/s

    burst: number * multiplier
    key: ${binary_remote_addr}
    zoneSize: size
```

### limit-whitelist

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/limit-whitelist: "CIDR"
```

ANIC:

```yaml
http-snippets: |
server-snippets: |
```

### rewrite-target

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/rewrite-target: "URI"
```

ANIC:

```yaml
rewritePath: "URI"
```

### Манипуляция заголовками

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"

nginx.ingress.kubernetes.io/cors-allow-headers: :samp:`X-Forwarded-For`

nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"

nginx.ingress.kubernetes.io/cors-allow-origin: "*"

nginx.ingress.kubernetes.io/cors-max-age: "seconds"
```

ANIC:

Установка для Ingress возможна с помощью аннотации `angie.software/location-snippets`.
Для работы в чарте необходимо установить `controller.enableSnippets` в `true`.

```yaml
Ingress:
annotations:
    angie.software/location-snippets |
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
```

```yaml
VirtualServer
responseHeaders:
  add:
    - name: Access-Control-Allow-Credentials
      value: "true"
    - name: Access-Control-Allow-Headers
      value: :samp:`X-Forwarded-For`
    - name: Access-Control-Allow-Methods
      value: "PUT, GET, POST, OPTIONS"
    - name: Access-Control-Allow-Origin
      value: "*"
    - name: Access-Control-Max-Age
      value: "seconds"
```

### Проксирование и балансировка нагрузки

В таблице ниже приведены аннотации Ingress-NGINX Controller и параметры в поле `upstream` для ресурсов VirtualServer и VirtualServerRoute.

| Ingress-NGINX Controller                                  | ANIC                    |
|-----------------------------------------------------------|-------------------------|
| `nginx.ingress.kubernetes.io/load-balance`                | `lb-method`             |
| `nginx.ingress.kubernetes.io/proxy-buffering`             | `buffering`             |
| `nnginx.ingress.kubernetes.io/proxy-buffers-number`       | `buffers`               |
| `nginx.ingress.kubernetes.io/proxy-next-upstream`         | `next-upstream`         |
| `nginx.ingress.kubernetes.io/proxy-next-upstream-timeout` | `next-upstream-timeout` |
| `nginx.ingress.kubernetes.io/proxy-read-timeout`          | `read-timeout`          |
| `nginx.ingress.kubernetes.io/proxy-send-timeout`          | `send-timeout`          |
| `nginx.ingress.kubernetes.io/service-upstream`            | `use-cluster-ip`        |

### Аутентификация mTLS

ANIC может обрабатывать аутентификацию mTLS на уровне входного трафика, требуя предоставления действительных сертификатов для внешних соединений. Настройка реализуется с помощью ресурсов Policy, соответствующих аннотациям Ingress-NGINX Controller.

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/auth-tls-secret: secretName
nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
```

ANIC:

```yaml
ingressMTLS:
   clientCertSecret: secretName
   verifyClient: "on"

   verifyDepth: 1
```

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/proxy-ssl-secret: "secretName"
nginx.ingress.kubernetes.io/proxy-ssl-verify: "on|off"
nginx.ingress.kubernetes.io/proxy-ssl-verify-depth: "1"
nginx.ingress.kubernetes.io/proxy-ssl-protocols: "TLSv1.2"
nginx.ingress.kubernetes.io/proxy-ssl-ciphers: "DEFAULT"
nginx.ingress.kubernetes.io/proxy-ssl-name: "server-name"
nginx.ingress.kubernetes.io/proxy-ssl-server-name: "on|off"
```

ANIC:

```yaml
egressMTLS:
   tlsSecret: secretName

   verifyServer: true|false

   verifyDepth: 1

   protocols: TLSv1.2

   ciphers: DEFAULT

   sslName: server-name

   serverName: true|false
```

### Сохранение сессий

Для сохранения сессий в ANIC используются ресурсы Policy. В Ingress-NGINX Controller используются соответствующие аннотации.

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "cookieName"
nginx.ingress.kubernetes.io/session-cookie-expires: "x"
nginx.ingress.kubernetes.io/session-cookie-path: "/route"
nginx.ingress.kubernetes.io/session-cookie-secure: "true"
```

ANIC:

```yaml
sessionCookie:
  enable: true

  name: cookieName

  expires: xh

  path: /route

  secure: true
```

### Аутентификация через внешний сервис

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/auth-url
```

ANIC:

Используется собственная реализация (применима только для VirtualServer): [настройка OIDC](https://angie.software//anic/docs/custom-resources/configuring-oidc.md#configuring-oidc).

### Привязка sticky-сессий через cookie

Ingress-NGINX Controller:

```yaml
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "cookie_name"
nginx.ingress.kubernetes.io/session-cookie-expires: "seconds"
nginx.ingress.kubernetes.io/session-cookie-path: "/route"
```

ANIC:

```yaml
angie.software/sticky-cookie-services: "serviceName=example-svc cookie_name expires=time path=/route"
```
