VirtualServer, VirtualServerRoute#

The VirtualServer and VirtualServerRoute resources implement use cases that are not supported by the Ingress resource, such as traffic splitting and advanced content-based routing. They are implemented as custom resources.

This is the reference documentation for both resources.

VirtualServer Specification#

The VirtualServer resource defines the load balancing configuration for a domain name, such as example.com. Below is an example of such a configuration:

apiVersion: k8s.angie.software/v1
kind: VirtualServer
metadata:
  name: cafe
spec:
  host: cafe.example.com
  tls:
    secret: cafe-secret
  staticLocations:
  - type: root
    urlPath: /americano
    dirPath: /latte
  gunzip: on
  upstreams:
  - name: tea
    service: tea-svc
    port: 80
  - name: coffee
    service: coffee-svc
    port: 80
  routes:
  - path: /tea
    action:
      pass: tea
  - path: /coffee
    action:
      pass: coffee
  - path: ~ ^/decaf/.\*\\.jpg$
    action:
      pass: coffee
  - path: = /green/tea
    action:
      pass: tea
  activeHealthProbes:
  - name: activename1
    upstream: tea
    uri: uri
    port:  80
    interval: 3s
    isEssential: true
    isPersistent: true
    maxBody: 10m
    fails: 4
    passes: 5
    mode: onfail
  maps:
  - variable: $jwt_claim_iat
    source: $oidc_client
    parameters:
      - value: 'myclient'
        result: '80'
  - variable: $jwt_claim_iss
    source: $oidc_client
    parameters:
      - value: 'myclient'
        result: 'PROVIDER_URL'
  - variable: $jwt_claim_sub
    source: $oidc_client
    parameters:
      - value: 'myclient'
        result: 'myclient'
  - variable: $jwt_claim_aud
    source: $oidc_client
    parameters:
      - value: 'myclient'
        result: 'myclient'

Field

Description

Type

Required

host

The host (domain name) of the server. It must be a valid subdomain as defined in RFC 1123, such as my-app or hello.example.com. When using a wildcard domain like *.example.com, the domain must be enclosed in double quotes. The host value must be unique among all Ingress and VirtualServer resources.

string

Yes

tls

TLS termination configuration.

tls

No

staticLocations

List of directories for serving static files.

[]staticLocations

No

gunzip

Enables or disables unpacking archived responses for clients. Valid pairs of values: "on" and "off", "true" and "false", or "yes" and "no". If the gunzip value is not set, the default is off.

boolean

No

ExternalDNS

ExternalDNS configuration for VirtualServer.

ExternalDNS

No

dos

Reference to DosProtectedResource; setting this parameter enables protection of the VirtualServer from DOS attacks.

string

No

policies

List of policies.

[]policy

No

upstreams

List of upstreams.

[]upstream

No

routes

List of routes.

[]route

No

activeHealthProbes

List of active health checks.

[]activeHealthProbes

No

maps

List of variables required for token validation during the OIDC authentication process.

[]maps

No

ingressClassName

Specifies which ANIC instance should handle the VirtualServer resource.

string

No

internalRoute

Indicates whether the VirtualServer resource is an internal route.

boolean

No

http-snippets

Specifies a custom snippet in the http context.

string

No

server-snippets

Specifies a custom snippet in the server context. It has priority over the ConfigMap key server-snippets.

string

No

VirtualServer.TLS#

The tls field defines the TLS configuration for the VirtualServer resource. For example:

secret: cafe-secret
redirect:
  enable: true
ssl_session_timeout: 1h
ssl_session_cache: shared:SSL:10m
ssl_session_tickets: on
ssl_stapling: on
ssl_stapling_verify: on

Field

Description

Type

Required

secret

The name of the secret with the TLS certificate and key. The secret must belong to the same namespace as the VirtualServer. The secret must be of type kubernetes.io/tls and contain the keys tls.crt and tls.key, which hold the certificate and private key, as described here. If the secret does not exist or is invalid, Angie will terminate any attempts to establish a TLS connection with the VirtualServer host. If no secret is specified but a wildcard TLS secret is configured, Angie will use the wildcard secret for TLS termination.

string

No

redirect

TLS redirect configuration for the VirtualServer.

tls.redirect

No

cert-manager

TLS cert-manager configuration for the VirtualServer.

tls.cert-manager

No

ssl_session_timeout

Specifies the time during which a client may reuse the session parameters. See also the ssl_session_timeout directive in the Angie documentation. Default value is 10m.

string

No

ssl_session_cache

Specifies the type and size of caches for storing session parameters. See also the ssl_session_cache directive in the Angie documentation. Default value is shared:SSL:10m.

string

No

ssl_session_tickets

Enables or disables session resumption using TLS session tickets. See also the ssl_session_tickets directive in the Angie documentation. Default value is off.

string

No

ssl_stapling

Enables or disables the server's ability to attach OCSP responses. See also the ssl_stapling directive in the Angie documentation. Default value is on.

string

No

ssl_stapling_verify

Enables or disables the server's ability to verify OCSP responses. See also the ssl_stapling_verify directive in the Angie documentation. Default value is on.

string

No

VirtualServer.TLS.Redirect#

The redirect field configures TLS redirection for the VirtualServer:

enable: true
code: 301
basedOn: scheme

Field

Description

Type

Required

enable

Enables TLS redirection for the VirtualServer. Default value is false.

boolean

No

code

The status code for redirection. Valid values: 301, 302, 307, 308. Default value is 301.

int

No

basedOn

The request attribute that Angie evaluates to send the redirect. Valid values are scheme (request scheme) or x-forwarded-proto (X-Forwarded-Proto request header). Default value is scheme.

string

No

VirtualServer.TLS.CertManager#

The cert-manager field configures the automatic management of x509 certificates for VirtualServer resources using cert-manager (cert-manager.io). Refer to the cert-manager configuration documentation for more information on deploying and configuring issuers. Example:

cert-manager:
  cluster-issuer: "my-issuer-name"

Field

Description

Type

Required

issuer

The name of the issuer. An issuer is a cert-manager resource that describes a certificate authority capable of signing certificates. It must be in the same namespace as the VirtualServer resource. Note that either issuer or cluster-issuer must be set, but these parameters are mutually exclusive—only one can be specified.

string

No

cluster-issuer

The name of the ClusterIssuer. A ClusterIssuer is a cert-manager resource that describes a certificate authority capable of signing certificates. It does not matter in which namespace your VirtualServer is, as ClusterIssuer resources are not namespace-bound. Note that either issuer or cluster-issuer must be set, but these parameters are mutually exclusive—only one can be specified.

string

No

issuer-kind

The type of external issuer resource, such as AWSPCAIssuer. This is only necessary for external issuers. It cannot be set if cluster-issuer is also set.

string

No

issuer-group

The API group of the external issuer controller, such as awspca.cert-manager.io. This is only necessary for external issuers. It cannot be set if cluster-issuer is also set.

string

No

common-name

This field allows you to configure spec.commonName for the certificate being created. This configuration adds a CN to the x509 certificate.

string

No

duration

This field allows you to configure the spec.duration field for the generated certificate. It must be specified using Go's time.Duration format, which does not support a d (days) suffix. Use s, m, and h suffixes instead.

string

No

renew-before

This annotation allows you to configure the spec.renewBefore field for the generated certificate. It must be specified using Go's time.Duration format, which does not support a d (days) suffix. Use s, m, and h suffixes instead.

string

No

usages

Allows you to configure the spec.usages field for the generated certificate. Provide a string of comma-separated values, such as "key agreement, digital signature, server authentication". The exhaustive list of supported key usages can be found in the cert-manager API documentation.

string

No

VirtualServer.ExternalDNS#

The ExternalDNS field configures dynamic DNS record management for VirtualServer resources using ExternalDNS. Refer to the ExternalDNS configuration documentation for more information on deployment and configuration of ExternalDNS and providers. Example:

enable: true

Field

Description

Type

Required

enable

Enables ExternalDNS integration for the VirtualServer resource. The default value is false.

string

No

labels

Configures labels applied to endpoint resources that will be used by ExternalDNS.

map[string]string

No

providerSpecific

Configures properties related to specific providers, containing the name and value of configuration specific to individual DNS providers.

[]ProviderSpecific

No

recordTTL

The TTL for the DNS record. By default, this value is 0. Refer to the ExternalDNS TTL documentation to determine default values for specific providers.

int64

No

recordType

The type of the created record, such as "A", "AAAA", "CNAME". If not specified, it will be automatically calculated based on external endpoints.

string

No

VirtualServer.ExternalDNS.ProviderSpecific#

The providerSpecific field in the ExternalDNS block allows you to specify provider-specific properties, which are a list of key-value pairs for configurations specific to individual DNS providers. Example:

- name: my-name
  value: my-value
- name: my-name2
  value: my-value2

Field

Description

Type

Required

name

The key in the key-value pair.

string

Yes

value

The value in the key-value pair.

string

Yes

VirtualServer.Policy#

References the Policy resource by name and optionally by namespace. For example:

name: access-control

Field

Description

Type

Required

name

The name of the policy. If the policy does not exist or is invalid, Angie will return a 500 status code error.

string

Yes

namespace

The namespace of the policy. If not specified, the namespace of the VirtualServer resource is used.

string

No

VirtualServer.Route#

A route defines rules for matching client requests with actions such as passing the request to an upstream. For example:

path: /tea
action:
  pass: tea

Field

Description

Type

Required

path

The path of the route. Angie will match it to the request URI. Possible values: prefix (/, /path), exact match (=/exact/match), case-insensitive regular expression (~*^/Bar.*\.jpg), or case-sensitive regular expression (~^/foo.*\.jpg). For prefixes (must start with /) or exact matches (must start with =), the path must not contain any whitespace, {, }, or ;. For regular expressions, all double quotes " must be escaped, and the match cannot end with an unescaped backslash \\. The path must be unique among the paths of all VirtualServer routes. See also the location directive.

string

Yes

policies

List of policies. These policies take precedence over policies of the same type defined in the spec of the VirtualServer. For more details, see Applying Policies.

[]policy

No

action

The default action to be performed for the request.

Action

No

dos

Reference to DosProtectedResource; setting this parameter enables DOS protection for the VirtualServer route.

string

No

splits

Default traffic splitting configuration. Must contain at least 2 splits.

Split

No

matches

Matching rules for advanced content-based routing. You must define a default action or splits. Unmatched requests will be handled by the default action or splits.

matches

No

route

The name of the VirtualServerRoute resource that defines this route. If the VirtualServerRoute is not in the same namespace as the VirtualServer, the namespace must be included. For example: tea-namespace/tea.

string

No

errorPages

Custom error responses. Angie will use these responses instead of returning upstream server errors or default Angie-generated responses. A custom response can be a redirect or a saved response. For example, this could be a redirect to another URL if the upstream server responded with a 404 status code.

[]errorPage

No

location-snippets

Specifies a custom snippet in the location context. It takes precedence over the ConfigMap key location-snippets.

string

No

Note

The route must include exactly one of the following actions: action, splits, or route.

Maps#

Defines the required variables $jwt_claim_iat, $jwt_claim_iss, $jwt_claim_sub, and $jwt_claim_aud for token validation during the OIDC authentication process.

- variable: $jwt_claim_iat
  source: $oidc_client
  parameters:
    - value: 'myclient'
      result: '80'
- variable: $jwt_claim_iss
  source: $oidc_client
  parameters:
    - value: 'myclient'
      result: 'PROVIDER_URL'
- variable: $jwt_claim_sub
  source: $oidc_client
  parameters:
    - value: 'myclient'
      result: 'myclient'
- variable: $jwt_claim_aud
  source: $oidc_client
  parameters:
    - value: 'myclient'
      result: 'myclient'

Example of enabling map variables based on input value (default, volatile, include, hostnames):

maps:
  - variable: $result_var
    source: $host
    parameters:
      - value: 'default'
        result: 'default_value'
      - value: 'volatile'
        result: ''
      - value: 'include'
        result: '/dev/stdout'
      - value: 'example.com'
        result: '1'
      - value: '*.example.com'
        result: '1'

See also the map directive in the Angie documentation.

Field

Description

Type

Required

$jwt_claim_iat

Configures the iat (issued at) claim for the client token.

string

Yes

$jwt_claim_iss

The iss (issuer) claim is matched against the PROVIDER_URL. This parameter identifies the service that issued the token.

string

Yes

$jwt_claim_sub

The sub (subject) claim identifies the user or subject for whom the token was issued.

string

Yes

$jwt_claim_aud

The aud (audience) claim identifies the client for which the token was intended.

string

Yes

VirtualServerRoute Specification#

The VirtualServerRoute resource defines routing for VirtualServer. It can consist of one or multiple nested routes. VirtualServerRoute is an alternative to combined Ingress types.

In the following example, the virtual server cafe in the cafe-ns namespace defines a route with the path /coffee, which is further defined through VirtualServerRoute coffee from the coffee-ns namespace.

VirtualServer:

apiVersion: k8s.angie.software/v1
kind: VirtualServer
metadata:
  name: cafe
  namespace: cafe-ns
spec:
  host: cafe.example.com
  upstreams:
  - name: tea
    service: tea-svc
    port: 80
  routes:
  - path: /tea
    action:
      pass: tea
  - path: /coffee
    route: coffee-ns/coffee

VirtualServerRoute:

apiVersion: k8s.angie.software/v1
kind: VirtualServerRoute
metadata:
  name: coffee
  namespace: coffee-ns
spec:
  host: cafe.example.com
  upstreams:
  - name: latte
    service: latte-svc
    port: 80
  - name: espresso
    service: espresso-svc
    port: 80
  subroutes:
  - path: /coffee/latte
    action:
      pass: latte
  - path: /coffee/espresso
    action:
      pass: espresso

Note that each nested route must have a path starting with the same prefix (in this case "/coffee") as the VirtualServer route. Additionally, the host in VirtualServerRoute must match the host in VirtualServer.

Field

Description

Type

Required

host

The host (domain name) of the server. It must be a valid subdomain as defined in RFC 1123, such as my-app or hello.example.com. For wildcard domains such as *.example.com, the domain must be enclosed in double quotes. The value must match the host in the VirtualServer that references this resource.

string

Yes

upstreams

List of upstreams.

[]upstream

No

subroutes

List of nested routes.

[]subroute

No

ingressClassName

Specifies which ANIC instance should handle the VirtualServerRoute resource. The value must match the ingressClassName in the VirtualServer that references this resource.

string

No

VirtualServerRoute.Subroute#

Defines the rules for matching client requests and actions, such as passing the request to an upstream. For example:

path: /coffee
action:
  pass: coffee

Field

Description

Type

Required

path

The path of the nested route. Angie will match it to the request URI. Possible values: prefix (/, /path), exact match (=/exact/match), case-insensitive regular expression (~*^/Bar.*\.jpg), or case-sensitive regular expression (~^/foo.*\.jpg). For prefixes, the path must start with the same path as the VirtualServer route that references this resource. For exact matches or regular expressions, the path must match the path of the VirtualServer route that references this resource. For prefixes or exact matches, the path must not contain any whitespace, {, }, or ;. For regular expressions, all double quotes " must be escaped, and the match cannot end with an unescaped backslash \\. The path must be unique among all the paths of the nested VirtualServerRoute routes.

string

Yes

policies

List of policies. These policies take precedence over all the policies defined in the VirtualServer route that references this resource. They also take precedence over policies of the same type defined in the spec of the VirtualServer. For more details, see Applying Policies.

[]policy

No

action

The default action to be performed for the request.

Action

No

dos

Reference to DosProtectedResource; setting this parameter enables DOS protection for the nested VirtualServerRoute route.

string

No

splits

Default traffic splitting configuration. Must contain at least 2 splits.

[]split

No

matches

Matching rules for advanced content-based routing. You must define a default action or splits. Unmatched requests will be handled by the default action or splits.

matches

No

errorPages

Custom error responses. Angie will use these responses instead of returning upstream server errors or default Angie-generated responses. A custom response can be a redirect or a saved response. For example, this could be a redirect to another URL if the upstream server responded with a 404 status code.

[]errorPage

No

location-snippets

Specifies a custom snippet in the location context. Overrides the value of location-snippets from the VirtualServer (if set) or the location-snippets key in the ConfigMap.

string

No

Note

The nested route must include exactly one of the following actions: action or splits.

Common Parts of VirtualServer and VirtualServerRoute#

Upstream#

The upstream defines the destination for routing configuration. For example:

name: tea
service: tea-svc
subselector:
  version: canary
port: 80
lb-method: round_robin
fail-timeout: 10s
max-fails: 1
max-conns: 32
keepalive: 32
connect-timeout: 30s
read-timeout: 30s
send-timeout: 30s
next-upstream: "error timeout non_idempotent"
next-upstream-timeout: 5s
next-upstream-tries: 10
client-max-body-size: 2m
tls:
  enable: true

Note

WebSocket protocol is supported without any additional configuration.

Field

Description

Type

Required

name

The name of the upstream. It must be a valid DNS label as defined in RFC 1035. For example, valid values are hello and upstream-123. The name must be unique among all upstreams in the resource.

string

Yes

service

The name of the service. The service must belong to the same namespace as the resource. If the service does not exist, Angie will assume it has no endpoints and will return a 502 response for requests to this upstream.

string

Yes

subselector

Selects pods within the service using label keys and values. By default, all service pods are selected.

Note

The specified labels must be present on the pods at the time of creation. If pod labels change, ANIC will not detect this change until the number of pods is modified.

map[string]string

No

use-cluster-ip

Allows the use of the cluster IP address and service port instead of using the pod IP address and port by default. When this field is enabled, fields that configure Angie behavior related to multiple upstream servers (such as lb-method and next-upstream) will have no effect, since ANIC will configure Angie with only one upstream server corresponding to the service's cluster IP address.

boolean

No

port

The service port. If the service does not define this port, Angie will assume it has no endpoints and will return a 502 response for requests to this upstream. The value must be in the range 1..65535.

uint16

Yes

lb-method

Load balancing method. To use round-robin, specify round_robin. The default value is specified in the ConfigMap key lb-method.

string

No

fail-timeout

The time during which the specified number of failed attempts to connect to the upstream server must occur for it to be considered unavailable. See the fail_timeout parameter of the server directive. The default value is specified in the ConfigMap key fail-timeout.

string

No

max-fails

The number of failed attempts to connect to the upstream server within the fail-timeout period before the server is considered unavailable. See the max_fails parameter of the server directive. The default value is specified in the ConfigMap key max-fails.

int

No

max-conns

The maximum number of concurrent active connections to the upstream server. See the max_conns parameter of the server directive. There is no limit by default.

Note

If keepalive connections are enabled, the total number of active and idle keepalive connections to the upstream server may exceed max-conns.

int

No

keepalive

Configures a cache for connections to upstream servers. A value of 0 disables the cache. See the keepalive directive. The default value is specified in the ConfigMap key keepalive.

int

No

connect-timeout

The timeout for establishing a connection to the upstream server. See the proxy_connect_timeout directive. The default value is specified in the ConfigMap key proxy-connect-timeout.

string

No

read-timeout

The timeout for reading a response from the upstream server. See the proxy_read_timeout directive. The default value is specified in the ConfigMap key proxy-read-timeout.

string

No

send-timeout

The timeout for sending a request to the upstream server. See the proxy_send_timeout directive. The default value is specified in the ConfigMap key proxy-send-timeout.

string

No

next-upstream

Specifies under what conditions the request should be passed to the next upstream server. See the proxy_next_upstream directive. The default value is error timeout.

string

No

next-upstream-timeout

The time during which a request may be passed to the next upstream server. See the proxy_next_upstream_timeout directive. A value of 0 disables the timeout. The default value is 0.

string

No

next-upstream-tries

The number of attempts to pass the request to the next upstream server. See the proxy_next_upstream_tries directive. A value of 0 disables the limit. The default value is 0.

int

No

client-max-body-size

Specifies the maximum size of the client's request body. See the client_max_body_size directive. The default value is specified in the ConfigMap key client-max-body-size.

string

No

tls

TLS configuration for the upstream.

tls

No

buffering

Enables buffering of responses from the upstream server. See the proxy_buffering directive. The default value is specified in the ConfigMap key proxy-buffering.

boolean

No

buffers

Configures the buffers used for reading the response from the upstream server in a single connection.

buffers

No

buffer-size

Sets the buffer size used for reading the first part of the response received from the upstream server. See the proxy_buffer_size directive. The default value is specified in the ConfigMap key proxy-buffer-size.

string

No

type

The type of upstream. Supported values are http and grpc. The default is http. For gRPC, you need to enable HTTP/2 in the ConfigMap and configure TLS termination on VirtualServer.

string

No

Upstream.Buffers#

Configures the buffers used for reading the response from the upstream server in a single connection.

number: 4
size: 8K

See the proxy_buffers directive for more information.

Field

Description

Type

Required

number

Specifies the number of buffers. The default value is specified in the ConfigMap key proxy-buffers.

int

Yes

size

Specifies the buffer size. If not set, the default is 8K. See also the ConfigMap key proxy-buffers.

string

No

Upstream.TLS#

Field

Description

Type

Required

enable

Enables HTTPS for requests to upstream servers. The default value is False, meaning HTTP will be used.

Note

By default, Angie will not verify the upstream server certificate. To enable verification, configure the EgressMTLS policy.

boolean

No

Upstream.SessionCookie#

The SessionCookie field configures session persistence, allowing requests from the same client to be directed to the same upstream server. The upstream server assignment is passed in a session cookie generated by Angie.

In the following example, we configure session persistence using a session cookie for the upstream and set all available parameters:

name: tea
service: tea-svc
port: 80
sessionCookie:
  enable: true
  name: srv_id
  path: /
  expires: 1h
  domain: .example.com
  httpOnly: false
  secure: true
  samesite: strict

See the sticky directive for more information. The session cookie corresponds to the sticky cookie method.

Field

Description

Type

Required

enable

Enables session persistence using a session cookie for the upstream server. The default value is false.

boolean

No

name

The name of the cookie.

string

Yes

path

The path for which the cookie is set.

string

No

expires

The time period during which the browser should retain the cookie. Can be set to the special value max, in which case the cookie will expire on December 31, 2037, at 23:55:55 UTC.

string

No

domain

The domain for which the cookie is set.

string

No

httpOnly

Adds the HttpOnly attribute to the cookie.

boolean

No

secure

Adds the Secure attribute to the cookie.

boolean

No

samesite

Adds the SameSite attribute to the cookie. Valid values are: strict, lax, none.

string

No

Upstream.SessionRoute#

The sessionRoute field configures route-based session persistence, allowing requests from the same client to be directed to the same upstream server. The upstream server assignment is maintained in Angie using the route mode.

In the following example, we configure the Angie directive sticky route  $cookie_route $arg_route;:

sessionRoute:
  enable: true
  variables:
    \- "\$cookie_route"
    \- "\$arg_route"

See the sticky route mode in the sticky directive for more details.

Parameters:

Field

Description

Type

Required

enable

Enables session persistence in route mode for the upstream server. The default value is false.

boolean

No

variables

A list of variables to be substituted into the sticky route directive in the order specified.

[]string

No

ActiveHealthProbes#

This field configures active health probes for the upstream. You need to define the probe's name and the upstream to which it applies, along with other parameters. For detailed descriptions of the active health probe parameters, refer to the Angie documentation, directive upstream_probe.

Example:

activeHealthProbes:
 - name: activename1
   upstream: tea-post
   uri: uri
   port:  80
   interval: 3s
   isEssential: true
   isPersistent: true
   maxBody: 10m
   fails: 4
   passes: 5
   mode: onfail

staticLocations#

This field defines the directory from which static files will be served. You can specify the root directory using the root directive or another location using the alias directive, refer to the Angie documentation for directive descriptions.

Configuration example:

staticLocations:
 - type: root
   urlPath: /static
   dirPath: /var/www/html

Field

Description

Type

Required

type

Specifies the method for defining the directory path from which static files will be served. Possible values: root, alias.

string

Yes

urlPath

The URL path prefix for requested static files, used in location; see the directive description in the Angie documentation.

string

Yes

dirPath

The directory from which requests for the specified URL path will be served.

string

Yes

Action#

Defines the action to be performed for the request.

In the example below, client requests are passed to the upstream coffee:

path: /coffee
action:
 pass: coffee

Field

Description

Type

Required

pass

Passes requests to the upstream server. The upstream with that name must be defined in the resource.

string

No

redirect

Redirects requests to the specified URL.

action.redirect

No

return

Returns a preconfigured response.

action.return

No

proxy

Passes requests to the upstream, with the ability to modify the request and response (e.g., rewrite the URI or modify headers).

action.proxy

No

Note

The action must include exactly one of the following values: pass, redirect, return, or proxy.

Action.Redirect#

Defines a redirect returned for the request.

In the example below, client requests are redirected to the URL http://myhost.ru:

redirect:
  url: http://myhost.ru
  code: 301

Field

Description

Type

Required

url

The URL to which the request will be redirected. Supported Angie variables: $scheme , $http_x_forwarded_proto , $request_uri , $host. Variables must be enclosed in curly braces. For example: ${host}${request_uri}.

string

Yes

code

The status code for the redirect. Valid values: 301, 302, 307, 308. Default value is 301.

int

No

Action.Return#

Defines a preconfigured response for the request.

In the example below, Angie will return a preconfigured response for every request:

return:
  code: 200
  type: text/plain
  body: "Hello World\n"

Field

Description

Type

Required

code

The response status code. Valid values: 2XX, 4XX, or 5XX. Default value is 200.

int

No

type

The MIME type of the response. Default value is text/plain.

string

No

body

The body of the response. Supports Angie variables. Variables must be enclosed in curly braces. For example: Request is ${request_uri}\n.

string

Yes

Note

Supported Angie variables: $request_uri, $request_method, $request_body, $scheme, $http_, $args, $arg_, $cookie_, $host, $request_time, $request_length, $angie_version, $pid, $connection, $remote_addr, $remote_port, $time_iso8601, $time_local, $server_addr, $server_port, $server_name, $server_protocol, $connections_active, $connections_reading, $connections_writing and $connections_waiting.

Action.Proxy#

Passes requests to the upstream with the ability to modify the request and response (e.g., rewrite the URI or modify headers).

In the example below, the request URI is rewritten to /, and request and response headers are modified:

proxy:
  upstream: coffee
  requestHeaders:
    pass: true
    set:
    - name: My-Header
      value: Value
    - name: Client-Cert
      value: ${ssl_client_escaped_cert}
  responseHeaders:
    add:
    - name: My-Header
      value: Value
    - name: IC-Angie-Version
      value: ${angie_version}
      always: true
    hide:
    - x-internal-version
    ignore:
    - Expires
    - Set-Cookie
    pass:
    - Server
  rewritePath: /

Field

Description

Type

Required

upstream

The name of the upstream to which requests will be proxied. The upstream with that name must be defined in the resource.

string

Yes

requestHeaders

Modifies the request headers.

Action.Proxy.RequestHeaders

No

responseHeaders

Modifies the response headers.

Action.Proxy.ResponseHeaders

No

rewritePath

Rewritten URI. If the route path is a regular expression, i.e., starts with ~, rewritePath can include capture groups $1-9. For example, $1 is the first group, and so on.

string

No

Action.Proxy.RequestHeaders#

The requestHeaders field modifies the request headers to the proxied upstream server.

Field

Description

Type

Required

pass

Passes the original request headers to the proxied upstream server. See the proxy_pass_request_headers directive. Default value is true.

bool

No

set

Allows overriding or adding fields to represent request headers passed to proxied upstream servers. See the proxy_set_header directive.

[]header

No

Action.Proxy.RequestHeaders.Set.Header#

Defines an HTTP header:

name: My-Header
value: My-Value

You can override the default Host header set by ANIC, which is set to $host:

name: Host
value: example.com

Field

Description

Type

Required

name

The name of the header.

string

Yes

value

The value of the header. Supports Angie variables. Variables must be enclosed in curly braces. For example: ${scheme}.

string

No

Note

Supported Angie variables: $request_uri, $request_method, $request_body, $scheme, $http_, $args, $arg_, $cookie_, $host, $request_time, $request_length, $angie_version, $pid, $connection, $remote_addr, $remote_port, $time_iso8601, $time_local, $server_addr, $server_port, $server_name, $server_protocol, $connections_active, $connections_reading, $connections_writing, $connections_waiting, $ssl_cipher, $ssl_ciphers, $ssl_client_cert, $ssl_client_escaped_cert, $ssl_client_fingerprint, $ssl_client_i_dn, $ssl_client_i_dn_legacy, $ssl_client_raw_cert, $ssl_client_s_dn, $ssl_client_s_dn_legacy, $ssl_client_serial, $ssl_client_v_end, $ssl_client_v_remain, $ssl_client_v_start, $ssl_client_verify, $ssl_curves, $ssl_early_data, $ssl_protocol, $ssl_server_name, $ssl_session_id, $ssl_session_reused.

Action.Proxy.ResponseHeaders#

The responseHeaders field modifies the response headers returned to the client.

Field

Description

Type

Required

hide

Headers that will not be passed to the client in the response from the proxied upstream server. See the proxy_hide_header directive.

[]string

No

pass

Allows passing hidden header fields to the client from the proxied upstream server. See the proxy_pass_header directive.

[]string

No

ignore

Disables the processing of certain headers when returning a response to the client from the proxied upstream server. See the proxy_ignore_headers directive.

[]string

No

add

Adds headers to the response returned to the client.

[]addHeader

No

Note

Default hidden headers: Date, Server, X-Pad, and X-Accel-....

Note

The following headers may be ignored: X-Accel-Redirect, X-Accel-Expires, X-Accel-Limit-Rate, X-Accel-Buffering, X-Accel-Charset, Expires, Cache-Control, Set-Cookie, and Vary.

AddHeader#

Defines an HTTP header with an optional always field:

name: My-Header
value: My-Value
always: true

Field

Description

Type

Required

name

The name of the header.

string

Yes

value

The value of the header. Supports Angie variables. Variables must be enclosed in curly braces. For example: ${scheme}.

string

No

always

If set to true, the header is added regardless of the response status code. The default value is false. For more details, refer to the add_header directive.

bool

No

Note

Supported Angie variables: $request_uri, $request_method, $request_body, $scheme, $http_, $args, $arg_, $cookie_, $host, $request_time, $request_length, $angie_version, $pid, $connection, $remote_addr, $remote_port, $time_iso8601, $time_local, $server_addr, $server_port, $server_name, $server_protocol, $connections_active, $connections_reading, $connections_writing, $connections_waiting, $ssl_cipher, $ssl_ciphers, $ssl_client_cert, $ssl_client_escaped_cert, $ssl_client_fingerprint, $ssl_client_i_dn, $ssl_client_i_dn_legacy, $ssl_client_raw_cert, $ssl_client_s_dn, $ssl_client_s_dn_legacy, $ssl_client_serial, $ssl_client_v_end, $ssl_client_v_remain, $ssl_client_v_start, $ssl_client_verify, $ssl_curves, $ssl_early_data, $ssl_protocol, $ssl_server_name, $ssl_session_id, $ssl_session_reused.

Note

If always is false, the response header is added only when the response status code is one of: 200, 201, 204, 206, 301, 302, 303, 304, 307, or 308.

Split#

Defines the weight of an action within the traffic splitting configuration.

In the example below, Angie passes 80% of requests to the upstream coffee-v1 and the remaining 20% to coffee-v2:

splits:
  - weight: 80
    action:
      pass: coffee-v1
  - weight: 20
    action:
      pass: coffee-v2

Field

Description

Type

Required

weight

The weight of the action. The value must be in the range 1..99. The sum of all split weights must equal 100.

int

Yes

action

The action to perform for the request.

Action

Yes

Match#

Defines matching between conditions and an action or traffic splits.

In the example below, Angie directs requests with the path "/coffee" to different upstreams based on the value of the user cookie:

  • user=john -> coffee-future

  • user=bob -> coffee-deprecated

  • If the cookie is not set or does not match john or bob, Angie redirects the request to coffee-stable

path: /coffee
matches:
- conditions:
  - cookie: user
    value: john
    action:
    pass: coffee-future
- conditions:
  - cookie: user
    value: bob
    action:
      pass: coffee-deprecated
  action:
    pass: coffee-stable

In the next example, Angie directs requests based on the value of the built-in variable $request_method, which represents the HTTP method of the request:

  • All POST requests -> coffee-post

  • All other requests -> coffee

path: /coffee
matches:
  - conditions:
    - variable: $request_method
      value: POST
    action:
      pass: coffee-post
    action:
      pass: coffee

Field

Description

Type

Required

conditions

List of conditions. Must include at least one condition.

[]condition

Yes

action

The action to perform for the request.

Action

No

splits

Traffic split configuration. There must be at least two splits.

[]split

No

Note

A match must use exactly one of the following values: action or splits.

Condition#

Defines a condition in a match.

Field

Description

Type

Required

header

The name of the header. Must consist of alphanumeric characters or -.

string

No

cookie

The name of the cookie. Must consist of alphanumeric characters or _.

string

No

argument

The name of the argument. Must consist of alphanumeric characters or _.

string

No

variable

The name of the Angie variable. Must start with $. See the list of supported variables below.

string

No

value

The value that the condition must match. How the value is determined is shown below in the table.

string

Yes

Note

A condition must include exactly one of the following: header, cookie, argument, or variable.

Supported Angie variables: $args, $http2, $https, $remote_addr, $remote_port, $query_string, $request, $request_body, $request_uri, $request_method, $scheme.

The value supports two types of matching:

  • Case-insensitive string comparison. For example:

    • john - case-insensitive match that succeeds for strings like john, John, JOHN.

    • !john - negation of case-insensitive match for john, which succeeds for strings like bob, anything, or "" (empty string).

  • Regular expression matching. Note that Angie supports Perl-compatible regular expressions (PCRE). For example:

    • ~^yes - case-sensitive regular expression matching any string that starts with yes, such as: yes, yes123.

    • !~^yes - negation of the previous regular expression, matching strings like YES, Yes123, or noyes. (The negation mechanism is not part of PCRE syntax).

    • ~*no$ -- case-insensitive regular expression matching any string that ends with no, such as: no, 123no, 123NO.

Note

The value must not contain unescaped double quotes (") and must not end with an unescaped backslash (\). For example, the following values are invalid: some"value, somevalue\.

ErrorPage#

Defines a custom response for a route when the upstream server responds with an error status code (or Angie generates one). The response can be a redirect or a stored response. For more details, refer to the error_page directive.

path: /coffee
errorPages:
  - codes: [502, 503]
    redirect:
      code: 301
      url: https://angie.software
  - codes: [404]
    return:
      code: 200
      body: "Original resource not found, but success!"

Field

Description

Type

Required

codes

List of error status codes.

[]int

Yes

redirect

Redirect action for the specified status codes.

errorPage.Redirect

No

return

Stored response action for the specified status codes.

errorPage.Return

No

Note

An error page must contain exactly one of the following: return or redirect.

ErrorPage.Redirect#

Defines a redirect for errorPage.

In the example below, Angie responds with a redirect when the upstream server returns a 404 status code.

codes: [404]
redirect:
  code: 301
  url: ${scheme}://cafe.example.com/error.html

Field

Description

Type

Required

code

The redirect status code. Allowed values: 301, 302, 307, 308. The default is 301.

int

No

url

The URL to which the request will be redirected. Supported Angie variables: $scheme and $http_x_forwarded_proto. Variables must be enclosed in curly braces. For example: ${scheme}.

string

Yes

ErrorPage.Return#

Defines a stored response for errorPage.

In the example below, Angie returns a stored response when the upstream server responds with status codes 401 or 403.

codes: [401, 403]
return:
  code: 200
  type: application/json
  body: |
    {\"msg\": \"You don't have permission to do this\"}
  headers:
    - name: x-debug-original-statuses
      value: ${upstream_status}

Field

Description

Type

Required

code

The response status code. The default is the status code of the original response.

int

No

type

The MIME type of the response. The default is text/html.

string

No

body

The body of the response. Supported Angie variable: $upstream_status. Variables must be enclosed in curly braces. For example: ${upstream_status}.

string

Yes

headers

Custom response headers.

errorPage.Return.Header

No

ErrorPage.Return.Header#

Defines an HTTP header for a stored errorPage response:

name: x-debug-original-statuses
value: ${upstream_status}

Field

Description

Type

Required

name

The name of the header.

string

Yes

value

The value of the header. Supported Angie variable: $upstream_status. Variables must be enclosed in curly braces. For example: ${upstream_status}.

string

No

Using VirtualServer and VirtualServerRoute#

You can manage VirtualServer and VirtualServerRoute resources using standard kubectl commands, similar to how you manage Ingress resources.

For example, the following command creates a VirtualServer resource defined in cafe-virtual-server.yaml with the name cafe:

kubectl apply -f cafe-virtual-server.yaml

virtualserver.k8s.angie.software "cafe" created

You can retrieve the resource by running:

kubectl get virtualserver cafe

NAME   STATE   HOST                   IP            PORTS      AGE
cafe   Valid   cafe.example.com       12.13.23.123  [80,443]   3m

In kubectl get and similar commands, you can also use the short name vs instead of virtualserver.

You can manage VirtualServerRoute resources similarly. In kubectl commands, use virtualserverroute or the short name vsr.

Using Snippets#

Snippets allow you to insert Angie configuration elements into various configuration contexts. In the example below, we use snippets to configure multiple Angie features for a VirtualServer:

apiVersion: k8s.angie.software/v1
kind: VirtualServer
metadata:
  name: cafe
  namespace: cafe
spec:
  http-snippets: |
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
    proxy_cache_path /tmp keys_zone=one:10m;
  host: cafe.example.com
  tls:
    secret: cafe-secret
  server-snippets: |
    limit_req zone=mylimit burst=20;
  upstreams:
    - name: tea
      service: tea-svc
      port: 80
    - name: coffee
      service: coffee-svc
      port: 80
  routes:
    - path: /tea
      location-snippets: |
        proxy_cache one;
        proxy_cache_valid 200 10m;
      action:
        pass: tea
    - path: /coffee
      action:
        pass: coffee

Snippets are intended for advanced Angie users who require more control over the generated Angie configuration.

However, due to the drawbacks described below, snippets are disabled by default. To use snippets, set the command-line argument enable-snippets.

Drawbacks of using snippets:

  • Complexity. To use snippets, you need to:

    • Understand Angie configuration primitives and implement the correct Angie configuration.

    • Understand how ANIC generates Angie configuration to ensure the snippet does not interfere with other configuration features.

  • Reduced reliability. An invalid snippet will make the Angie configuration invalid, resulting in an error during reload. This will prevent any configuration updates, including updates for other VirtualServer and VirtualServerRoute resources, until the snippet is fixed.

  • Security implications. Snippets provide access to Angie configuration primitives, and these primitives are not validated by ANIC. For example, a snippet could configure Angie to serve arbitrary TLS certificates and keys used for TLS termination on Ingress and VirtualServer resources.

To help catch errors when using snippets, ANIC reports configuration reload errors in the logs, as well as in the events and status fields of VirtualServer and VirtualServerRoute resources.

Note

While the Angie configuration contains an invalid snippet, Angie will continue to run with the last valid configuration.

Validation#

There are two types of validation available for VirtualServer and VirtualServerRoute resources:

  • Structural validation using kubectl and the Kubernetes API server.

  • Comprehensive validation using ANIC.

Structural Validation#

The custom resource definitions for VirtualServer and VirtualServerRoute include an OpenAPI schema that describes the type of each field in these resources.

If you attempt to create (or update) a resource that violates the structural schema (for example, using a string value for an upstream port field), kubectl and the Kubernetes API server will reject the resource:

  • Example of kubectl validation:

    kubectl apply -f cafe-virtual-server.yaml
    
      error: error validating "cafe-virtual-server.yaml": error validating
      data: ValidationError(VirtualServer.spec.upstreams[0].port): invalid
      type for software.angie.k8s.v1.VirtualServer.spec.upstreams.port: got
      "string", expected "integer"; if you choose to ignore these errors,
      turn validation off with --validate=false
    
  • Example of Kubernetes API server validation:

    kubectl apply -f cafe-virtual-server.yaml --validate=false
    
      The VirtualServer "cafe" is invalid: []: Invalid value:
      map[string]interface {}{ ... }: validation failure list:
      spec.upstreams.port in body must be of type integer: "string"
    

If the resource is not rejected (i.e., does not violate the structural schema), ANIC will validate it further.

Comprehensive Validation#

ANIC validates the fields of VirtualServer and VirtualServerRoute resources. If a resource is invalid, ANIC will reject it: the resource will still exist in the cluster, but ANIC will ignore it.

You can check if ANIC successfully applied the configuration for a VirtualServer. For our example VirtualServer cafe, we can run:

kubectl describe vs cafe

. . .
Events:
  Type    Reason          Age   From                      Message
  -----
  Normal  AddedOrUpdated  16s   angie-ingress-controller  Configuration for default/cafe was added or updated

Note that the "Events" section includes a Normal event with the reason AddedOrUpdated, informing us that the configuration was successfully applied.

If you create an invalid resource, ANIC will reject it and issue a Rejected event. For example, if you create a VirtualServer cafe with two upstreams named tea, you will receive:

kubectl describe vs cafe

. . .
Events:
  Type     Reason    Age   From                      Message
  -----
  Warning  Rejected  12s   angie-ingress-controller  VirtualServer default/cafe is invalid and was rejected: spec.upstreams[1].name: Duplicate value: "tea"

Note that the "Events" section includes a warning event indicating the reason for rejection.

Additionally, this information is also available in the status field of the VirtualServer resource. Note the Status section of the VirtualServer:

kubectl describe vs cafe

. . .
Status:
  External Endpoints:
    Ip:        12.13.23.123
    Ports:     [80,443]
  Message:  VirtualServer default/cafe is invalid and was rejected: spec.upstreams[1].name: Duplicate value: "tea"
  Reason:   Rejected
  State:    Invalid

ANIC validates VirtualServerRoute resources in a similar manner.

Note

If you introduce an error in an existing resource, ANIC will reject it and remove the corresponding configuration from Angie.

Configuring via ConfigMap#

You can further configure Angie for VirtualServer and VirtualServerRoutes resources using ConfigMap. Most ConfigMap keys are supported, with the following exceptions:

  • proxy-hide-headers

  • proxy-pass-headers

  • hsts

  • hsts-max-age

  • hsts-include-subdomains

  • hsts-behind-proxy

  • redirect-to-https

  • ssl-redirect