<a id="advanced-routing"></a>

# Расширенная маршрутизация

Ниже приведен пример настройки расширенной маршрутизации с помощью ресурса VirtualServer для приложения "cafe" из примера настройки базовой конфигурации.

Внесены следующие изменения:

- Вместо одной версии сервиса `tea` теперь две: `tea-post-svc` и `tea-svc`.
  POST-запросы для `tea` направляются в `tea-post-svc`.
  Остальные запросы (например, GET) направляются в `tea-svc`.
- Вместо одной версии сервиса `coffee` теперь две: `coffee-v1-svc` и `coffee-v2-svc`.
  Запросы, содержащие cookie `version=v2`, направляются в `coffee-v2-svc`.
  Все остальные запросы направляются в `coffee-v1-svc`.
- Для упрощения из примера удалена поддержка TLS.

## Предварительные действия

1. Установите ANIC с включенными пользовательскими ресурсами.
2. Сохраните публичный IP-адрес ANIC в переменной оболочки:
   ```console
   $ IC_IP=<ваш_IP-адрес>
   ```
3. Сохраните HTTP-порт ANIC в переменной оболочки:
   ```console
   $ IC_HTTP_PORT=<номер порта>
   ```

## Настройка расширенной маршрутизации

1. Создайте Deployment и Service для `coffee` и `tea`:
   ```yaml
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: coffee-v1
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: coffee-v1
     template:
       metadata:
         labels:
           app: coffee-v1
       spec:
         containers:
         - name: coffee-v1
           image: angiesoftware/angie-hello:plain-text
           ports:
           - containerPort: 8080
   ---
   apiVersion: v1
   kind: Service
   metadata:
     name: coffee-v1-svc
   spec:
     ports:
     - port: 80
       targetPort: 8080
       protocol: TCP
       name: http
     selector:
       app: coffee-v1
   ---
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: coffee-v2
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: coffee-v2
     template:
       metadata:
         labels:
           app: coffee-v2
       spec:
         containers:
         - name: coffee-v2
           image: angiesoftware/angie-hello:plain-text
           ports:
           - containerPort: 8080
   ---
   apiVersion: v1
   kind: Service
   metadata:
     name: coffee-v2-svc
   spec:
     ports:
     - port: 80
       targetPort: 8080
       protocol: TCP
       name: http
     selector:
       app: coffee-v2
   ---
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: tea-post
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: tea-post
     template:
       metadata:
         labels:
           app: tea-post
       spec:
         containers:
         - name: tea-post
           image: angiesoftware/angie-hello:plain-text
           ports:
           - containerPort: 8080
   ---
   apiVersion: v1
   kind: Service
   metadata:
     name: tea-post-svc
   spec:
     ports:
     - port: 80
       targetPort: 8080
       protocol: TCP
       name: http
     selector:
       app: tea-post
   ---
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: tea
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: tea
     template:
       metadata:
         labels:
           app: tea
       spec:
         containers:
         - name: tea
           image: angiesoftware/angie-hello:plain-text
           ports:
           - containerPort: 8080
   ---
   apiVersion: v1
   kind: Service
   metadata:
     name: tea-svc
   spec:
     ports:
     - port: 80
       targetPort: 8080
       protocol: TCP
       name: http
     selector:
       app: tea
   ```

   Примените настройки:
   ```console
   $ kubectl create -f cafe.yaml
   ```
2. Создайте ресурс VirtualServer:
   ```yaml
   apiVersion: k8s.angie.software/v1
   kind: VirtualServer
   metadata:
     name: cafe
   spec:
     host: cafe.example.com
     upstreams:
     - name: tea-post
       service: tea-post-svc
       port: 80
     - name: tea
       service: tea-svc
       port: 80
     - name: coffee-v1
       service: coffee-v1-svc
       port: 80
     - name: coffee-v2
       service: coffee-v2-svc
       port: 80
     routes:
     - path: /tea
       authRequest: /auth/path
       authRequestSets:
         - key: foo
           value: bar
       matches:
       - conditions:
         - variable: $request_method
           value: POST
         action:
           pass: tea-post
       action:
         pass: tea-post
     - path: /coffee
       matches:
       - conditions:
         - cookie: version
           value: v2
         action:
           pass: coffee-v2
       action:
         pass: coffee-v1
     authRequestLocations:
       - path: /auth/path
         proxyPass:
           upstreamName: "tea"
         proxyPassHeaders:
           - key: Content-Length
             value: "100"
   ```

   Примените настройки:
   ```console
   $ kubectl create -f cafe-virtual-server.yaml
   ```
3. Протестируйте конфигурацию.

   Проверьте, что конфигурация была успешно применена, просмотрев события ресурса VirtualServer:
   ```console
   $ kubectl describe virtualserver cafe
   ```

   Вывод:
   ```console
   Events:
     Type    Reason          Age   From                      Message
     ----    ------          ----  ----                      -------
     Normal  AddedOrUpdated  2s    ANIC                      Configuration for default/cafe was added or updated
   ```
4. Протестируйте доступ к сервису `tea`.

   Отправьте POST-запрос и убедитесь, что ответ приходит от `tea-post-svc`:
   ```console
   $ curl --resolve cafe.example.com:$IC_HTTP_PORT:$IC_IP http://cafe.example.com:$IC_HTTP_PORT/tea -X POST
   ```

   Ожидаемый результат:
   ```console
   Server address: 10.16.1.188:80
   Server name: tea-post-b5dd479b4-6ssmh
   . . .
   ```

   Отправьте GET-запрос и убедитесь, что ответ приходит от `tea-svc`:
   ```console
   $ curl --resolve cafe.example.com:$IC_HTTP_PORT:$IC_IP http://cafe.example.com:$IC_HTTP_PORT/tea
   ```

   Ожидаемый результат:
   ```console
   Server address: 10.16.1.189:80
   Server name: tea-7d57856c44-2hsvr
   . . .
   ```
5. Протестируйте доступ к сервису `coffee`.

   Отправьте запрос с cookie `version=v2` и убедитесь, что ответ приходит от `coffee-v2-svc`:
   ```console
   $ curl --resolve cafe.example.com:$IC_HTTP_PORT:$IC_IP http://cafe.example.com:$IC_HTTP_PORT/coffee --cookie "version=v2"
   ```

   Ожидаемый результат:
   ```console
   Server address: 10.16.1.187:80
   Server name: coffee-v2-7fd446968b-vkthp
   . . .
   ```

   Отправьте запрос без cookie и убедитесь, что ответ приходит от `coffee-v1-svc`:
   ```console
   $ curl --resolve cafe.example.com:$IC_HTTP_PORT:$IC_IP http://cafe.example.com:$IC_HTTP_PORT/coffee
   ```

   Ожидаемый результат:
   ```console
   Server address: 10.16.0.153:80
   Server name: coffee-v1-78754bdcfb-bs9nh
   . . .
   ```
