Ingress annotations¶
You can add kubernetes annotations to ingress and service objects to customize their behavior.
Note
- Annotations applied to service have higher priority over annotations applied to ingress.
Location
column below indicates where that annotation can be applied to. - Annotation keys and values can only be strings. Advanced format are encoded as below:
- boolean: 'true'
- integer: '42'
- stringMap: k1=v1,k2=v2
- stringList: s1,s2,s3
- json: 'jsonContent'
Tip
The annotation prefix can be changed using the --annotations-prefix
command line argument, by default it's alb.ingress.kubernetes.io
, as described in the table below.
Annotations¶
Traffic Listening¶
Traffic Listening can be controlled with following annotations:
-
alb.ingress.kubernetes.io/listen-ports
specifies the ports that ALB used to listen on.defaults to
'[{"HTTP": 80}]'
or'[{"HTTPS": 443}]'
depends on whethercertificate-arn
is specified.Example
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}, {"HTTP": 8080}, {"HTTPS": 8443}]'
You may not have duplicate load balancer ports defined.
-
alb.ingress.kubernetes.io/ip-address-type
specifies the IP address type of ALB.Example
alb.ingress.kubernetes.io/ip-address-type: ipv4
Traffic Routing¶
Traffic Routing can be controlled with following annotations:
-
alb.ingress.kubernetes.io/target-type
specifies how to route traffic to pods. You can choose betweeninstance
andip
:-
instance
mode will route traffic to all ec2 instances within cluster on NodePort opened for your service.service must be of type "NodePort" or "LoadBalancer" to use
instance
mode -
ip
mode will route traffic directly to the pod IP.network plugin must use secondary IP addresses on ENI for pod IP to use
ip
mode. e.g.
Example
alb.ingress.kubernetes.io/target-type: instance
-
-
alb.ingress.kubernetes.io/backend-protocol
specifies the protocol used when route traffic to pods.Example
alb.ingress.kubernetes.io/backend-protocol: HTTPS
-
alb.ingress.kubernetes.io/subnets
specifies the Availability Zone that ALB will route traffic to. See Load Balancer subnets for more details.You must specify at least two subnets in different AZ. both subnetID or subnetName(Name tag on subnets) can be used.
Tip
You can enable subnet auto discovery to avoid specify this annotation on every ingress. See Subnet Auto Discovery for instructions.
Example
alb.ingress.kubernetes.io/subnets: subnet-xxxx, mySubnet
-
alb.ingress.kubernetes.io/actions.${action-name}
Provides a method for configuring custom actions on a listener, such as for Redirect Actions.The
action-name
in the annotation must match the serviceName in the ingress rules, and servicePort must beuse-annotation
.Example
- response-503: return fixed 503 response
- redirect-to-eks: redirect to an external url
- forward-single-tg: forward to an single targetGroup [simplified schema]
- forward-multiple-tg: forward to multiple targetGroups with different weights and stickiness config [advanced schema]
apiVersion: extensions/v1beta1 kind: Ingress metadata: namespace: default name: ingress annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/actions.response-503: > {"Type":"fixed-response","FixedResponseConfig":{"ContentType":"text/plain","StatusCode":"503","MessageBody":"503 error text"}} alb.ingress.kubernetes.io/actions.redirect-to-eks: > {"Type":"redirect","RedirectConfig":{"Host":"aws.amazon.com","Path":"/eks/","Port":"443","Protocol":"HTTPS","Query":"k=v","StatusCode":"HTTP_302"}} alb.ingress.kubernetes.io/actions.forward-single-tg: > {"Type":"forward","TargetGroupArn": "arn-of-your-target-group"} alb.ingress.kubernetes.io/actions.forward-multiple-tg: > {"Type":"forward","ForwardConfig":{"TargetGroups":[{"ServiceName":"service-1","ServicePort":"80","Weight":20},{"ServiceName":"service-2","ServicePort":"80","Weight":20},{"TargetGroupArn":"arn-of-your-non-k8s-target-group","Weight":60}],"TargetGroupStickinessConfig":{"Enabled":true,"DurationSeconds":200}}} spec: rules: - http: paths: - path: /503 backend: serviceName: response-503 servicePort: use-annotation - path: /eks backend: serviceName: redirect-to-eks servicePort: use-annotation - path: /path1 backend: serviceName: forward-single-tg servicePort: use-annotation - path: /path2 backend: serviceName: forward-multiple-tg servicePort: use-annotation
use ARN in forward Action
ARN can be used in forward action(both simplified schema and advanced schema), it must be an targetGroup created outside of k8s, typically an targetGroup for legacy application.
use ServiceName/ServicePort in forward Action
ServiceName/ServicePort can be used in forward action(advanced schema only).
Limitation: Auth related annotations on Service object won't be respected, it must be applied to Ingress object.
-
alb.ingress.kubernetes.io/conditions.${conditions-name}
Provides a method for specifying routing conditions in addition to original host/path condition on Ingress spec.The
conditions-name
in the annotation must match the serviceName in the ingress rules. It can be a either real serviceName or an annotation based action name when servicePort is "use-annotation".Example
- rule-path1:
- Host is www.example.com OR anno.example.com
- Path is /path1
- rule-path2:
- Host is www.example.com
- Path is /path2 OR /anno/path2
- rule-path3:
- Host is www.example.com
- Path is /path3
- Http header HeaderName is HeaderValue1 OR HeaderValue2
- rule-path4:
- Host is www.example.com
- Path is /path4
- Http request method is GET OR HEAD
- rule-path5:
- Host is www.example.com
- Path is /path5
- Query string is paramA:valueA1 OR paramA:valueA2
- rule-path6:
- Host is www.example.com
- Path is /path6
- Source IP is192.168.0.0/16 OR 172.16.0.0/16
- rule-path7:
- Host is www.example.com
- Path is /path6
- Http header HeaderName is HeaderValue
- Query string is paramA:valueA
- Query string is paramB:valueB
apiVersion: extensions/v1beta1 kind: Ingress metadata: namespace: default name: ingress annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/actions.rule-path1: > {"Type":"fixed-response","FixedResponseConfig":{"ContentType":"text/plain","StatusCode":"200","MessageBody":"Host is www.example.com OR anno.example.com"}} alb.ingress.kubernetes.io/conditions.rule-path1: > [{"Field":"host-header","HostHeaderConfig":{"Values":["anno.example.com"]}}] alb.ingress.kubernetes.io/actions.rule-path2: > {"Type":"fixed-response","FixedResponseConfig":{"ContentType":"text/plain","StatusCode":"200","MessageBody":"Path is /path2 OR /anno/path2"}} alb.ingress.kubernetes.io/conditions.rule-path2: > [{"Field":"path-pattern","PathPatternConfig":{"Values":["/anno/path2"]}}] alb.ingress.kubernetes.io/actions.rule-path3: > {"Type":"fixed-response","FixedResponseConfig":{"ContentType":"text/plain","StatusCode":"200","MessageBody":"Http header HeaderName is HeaderValue1 OR HeaderValue2"}} alb.ingress.kubernetes.io/conditions.rule-path3: > [{"Field":"http-header","HttpHeaderConfig":{"HttpHeaderName": "HeaderName", "Values":["HeaderValue1", "HeaderValue2"]}}] alb.ingress.kubernetes.io/actions.rule-path4: > {"Type":"fixed-response","FixedResponseConfig":{"ContentType":"text/plain","StatusCode":"200","MessageBody":"Http request method is GET OR HEAD"}} alb.ingress.kubernetes.io/conditions.rule-path4: > [{"Field":"http-request-method","HttpRequestMethodConfig":{"Values":["GET", "HEAD"]}}] alb.ingress.kubernetes.io/actions.rule-path5: > {"Type":"fixed-response","FixedResponseConfig":{"ContentType":"text/plain","StatusCode":"200","MessageBody":"Query string is paramA:valueA1 OR paramA:valueA2"}} alb.ingress.kubernetes.io/conditions.rule-path5: > [{"Field":"query-string","QueryStringConfig":{"Values":[{"Key":"paramA","Value":"valueA1"},{"Key":"paramA","Value":"valueA2"}]}}] alb.ingress.kubernetes.io/actions.rule-path6: > {"Type":"fixed-response","FixedResponseConfig":{"ContentType":"text/plain","StatusCode":"200","MessageBody":"Source IP is 192.168.0.0/16 OR 172.16.0.0/16"}} alb.ingress.kubernetes.io/conditions.rule-path6: > [{"Field":"source-ip","SourceIpConfig":{"Values":["192.168.0.0/16", "172.16.0.0/16"]}}] alb.ingress.kubernetes.io/actions.rule-path7: > {"Type":"fixed-response","FixedResponseConfig":{"ContentType":"text/plain","StatusCode":"200","MessageBody":"multiple conditions applies"}} alb.ingress.kubernetes.io/conditions.rule-path7: > [{"Field":"http-header","HttpHeaderConfig":{"HttpHeaderName": "HeaderName", "Values":["HeaderValue"]}},{"Field":"query-string","QueryStringConfig":{"Values":[{"Key":"paramA","Value":"valueA"}]}},{"Field":"query-string","QueryStringConfig":{"Values":[{"Key":"paramB","Value":"valueB"}]}}] spec: rules: - host: www.example.com http: paths: - path: /path1 backend: serviceName: rule-path1 servicePort: use-annotation - path: /path2 backend: serviceName: rule-path2 servicePort: use-annotation - path: /path3 backend: serviceName: rule-path3 servicePort: use-annotation - path: /path4 backend: serviceName: rule-path4 servicePort: use-annotation - path: /path5 backend: serviceName: rule-path5 servicePort: use-annotation - path: /path6 backend: serviceName: rule-path6 servicePort: use-annotation - path: /path7 backend: serviceName: rule-path7 servicePort: use-annotation
limitations
General ALB limitations applies:
-
Each rule can optionally include up to one of each of the following conditions: host-header, http-request-method, path-pattern, and source-ip. Each rule can also optionally include one or more of each of the following conditions: http-header and query-string.
-
You can specify up to three match evaluations per condition.
-
You can specify up to five match evaluations per rule.
Refer ALB documentation for more details.
- rule-path1:
Access control¶
Access control for LoadBalancer can be controlled with following annotations:
-
alb.ingress.kubernetes.io/scheme
specifies whether your LoadBalancer will be internet facing. See Load balancer scheme in the AWS documentation for more details.Example
alb.ingress.kubernetes.io/scheme: internal
-
alb.ingress.kubernetes.io/inbound-cidrs
specifies the CIDRs that are allowed to access LoadBalancer.this annotation will be ignored if
alb.ingress.kubernetes.io/security-groups
is specified.Example
alb.ingress.kubernetes.io/inbound-cidrs: 10.0.0.0/24
-
alb.ingress.kubernetes.io/security-groups
specifies the securityGroups you want to attach to LoadBalancer.When this annotation is not present, the controller will automatically create 2 security groups: the first security group will be attached to the LoadBalancer and allow access from
inbound-cidrs
to thelisten-ports
. The second security group will be attached to the EC2 instance(s) and allow all TCP traffic from the first security group created for the LoadBalancer.Both name or ID of securityGroups are supported. Name matches a
Name
tag, not thegroupName
attribute.The default limit of security groups per network interface in AWS is 5. This limit is quickly reached when multiple load balancers are provisioned by the controller without this annotation, therefore it is recommended to set this annotation to a self-managed security group (or request AWS support to increase the number of security groups per network interface for your AWS account). If this annotation is specified, you should also manage the security group used by the EC2 instances to allow inbound traffic from the security group attached to the LoadBalancer.
Example
alb.ingress.kubernetes.io/security-groups: sg-xxxx, nameOfSg1, nameOfSg2
Authentication¶
ALB supports authentication with Cognito or OIDC. See Authenticate Users Using an Application Load Balancer for more details.
HTTPS only
Authentication is only supported for HTTPS listeners, see SSL for configure HTTPS listener.
-
alb.ingress.kubernetes.io/auth-type
specifies the authentication type on targets.Example
alb.ingress.kubernetes.io/auth-type: cognito
-
alb.ingress.kubernetes.io/auth-idp-cognito
specifies the cognito idp configuration.If you are using Amazon Cognito Domain, the
UserPoolDomain
should be set to the domain prefix(xxx) instead of full domain(https://xxx.auth.us-west-2.amazoncognito.com)Example
alb.ingress.kubernetes.io/auth-idp-cognito: '{"UserPoolArn":"arn:aws:cognito-idp:us-west-2:xxx:userpool/xxx", "UserPoolClientId":"xxx", "UserPoolDomain":"xxx"}'
-
alb.ingress.kubernetes.io/auth-idp-oidc
specifies the oidc idp configuration.You need to create an secret within the same namespace as ingress to hold your OIDC clientID and clientSecret. The format of secret is as below:
apiVersion: v1 kind: Secret metadata: namespace: testcase name: customizedSecretName data: clientId: base64 of your plain text clientId clientSecret: base64 of your plain text clientSecret
Example
alb.ingress.kubernetes.io/auth-idp-oidc: '{"Issuer":"xxx","AuthorizationEndpoint":"xxx","TokenEndpoint":"xxx","UserInfoEndpoint":"xxx","SecretName":"customizedSecretName"}'
-
alb.ingress.kubernetes.io/auth-on-unauthenticated-request
specifies the behavior if the user is not authenticated.options:
- authenticate: try authenticate with configured IDP.
- deny: return an HTTP 401 Unauthorized error.
- allow: allow the request to be forwarded to the target.
Example
alb.ingress.kubernetes.io/auth-on-unauthenticated-request: authenticate
-
alb.ingress.kubernetes.io/auth-scope
specifies the set of user claims to be requested from the IDP(cognito or oidc), in a space-separated list.options:
- phone
- profile
- openid
- aws.cognito.signin.user.admin
Example
alb.ingress.kubernetes.io/auth-scope: 'email openid'
-
alb.ingress.kubernetes.io/auth-session-cookie
specifies the name of the cookie used to maintain session informationExample
alb.ingress.kubernetes.io/auth-session-cookie: custom-cookie
-
alb.ingress.kubernetes.io/auth-session-timeout
specifies the maximum duration of the authentication session, in secondsExample
alb.ingress.kubernetes.io/auth-session-timeout: '86400'
Health Check¶
Health check on target groups can be controlled with following annotations:
-
alb.ingress.kubernetes.io/healthcheck-protocol
specifies the protocol used when performing health check on targets.default protocol can be set via
--backend-protocol
flagExample
alb.ingress.kubernetes.io/healthcheck-protocol: HTTPS
-
alb.ingress.kubernetes.io/healthcheck-port
specifies the port used when performing health check on targets.Example
- set the healthcheck port to the traffic port
alb.ingress.kubernetes.io/healthcheck-port: traffic-port
- set the healthcheck port to the NodePort(when target-type=instance) or TargetPort(when target-type=ip) of a named port
alb.ingress.kubernetes.io/healthcheck-port: my-port
- set the healthcheck port to 80/tcp
alb.ingress.kubernetes.io/healthcheck-port: '80'
When using
target-type: instance
with a service of type "NodePort", the healthcheck port can be set totraffic-port
to automatically point to the correct port. - set the healthcheck port to the traffic port
-
alb.ingress.kubernetes.io/healthcheck-path
specifies the HTTP path when performing health check on targets.Example
alb.ingress.kubernetes.io/healthcheck-path: /ping
-
alb.ingress.kubernetes.io/healthcheck-interval-seconds
specifies the interval(in seconds) between health check of an individual target.Example
alb.ingress.kubernetes.io/healthcheck-interval-seconds: '10'
-
alb.ingress.kubernetes.io/healthcheck-timeout-seconds
specifies the timeout(in seconds) during which no response from a target means a failed health checkExample
alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '8'
-
alb.ingress.kubernetes.io/success-codes
specifies the HTTP status code that should be expected when doing health checks against the specified health check path.Example
- use single value
alb.ingress.kubernetes.io/success-codes: '200'
- use multiple values
alb.ingress.kubernetes.io/success-codes: 200,201
- use range of value
alb.ingress.kubernetes.io/success-codes: 200-300
- use single value
-
alb.ingress.kubernetes.io/healthy-threshold-count
specifies the consecutive health checks successes required before considering an unhealthy target healthy.Example
alb.ingress.kubernetes.io/healthy-threshold-count: '2'
-
alb.ingress.kubernetes.io/unhealthy-threshold-count
specifies the consecutive health check failures required before considering a target unhealthy.Example
alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
WAF¶
-
alb.ingress.kubernetes.io/waf-acl-id
specifies the identifier for the Amzon WAF web ACL.Only Regional WAF is supported.
Example
alb.ingress.kubernetes.io/waf-acl-id: 499e8b99-6671-4614-a86d-adb1810b7fbe
WAFv2¶
-
alb.ingress.kubernetes.io/wafv2-acl-arn
specifies ARN for the Amazon WAFv2 web ACL.Only Regional WAFv2 is supported.
Example
alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:us-west-2:xxxxx:regional/webacl/xxxxxxx/3ab78708-85b0-49d3-b4e1-7a9615a6613b
To get the WAFv2 Web ACL ARN from the Console, click the gear icon in the upper right and enable the ARN column.
Shield Advanced¶
-
alb.ingress.kubernetes.io/shield-advanced-protection
turns on / off the AWS Shield Advanced protection for the load balancer.Example
alb.ingress.kubernetes.io/shield-advanced-protection: 'true'
SSL¶
SSL support can be controlled with following annotations:
-
alb.ingress.kubernetes.io/certificate-arn
specifies the ARN of one or more certificate managed by AWS Certificate ManagerThe first certificate in the list will be added as default certificate. And remaining certificate will be added to the optional certificate list. See SSL Certificates for more details.
Example
- single certificate
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:xxxxx:certificate/xxxxxxx
- multiple certificates
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:xxxxx:certificate/cert1,arn:aws:acm:us-west-2:xxxxx:certificate/cert2,arn:aws:acm:us-west-2:xxxxx:certificate/cert3
Tip
If the
alb.ingress.kubernetes.io/certificate-arn
annotation is not specified, the controller will attempt to add certificates to listeners that require it by matching available certs from ACM with thehost
field in each listener's ingress rule.Example
- attaches a cert for
dev.example.com
or*.example.com
to the ALBapiVersion: extensions/v1beta1 kind: Ingress metadata: namespace: default name: ingress annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' spec: rules: - host: dev.example.com http: paths: - path: /users/* backend: serviceName: user-service servicePort: 80
Tip
Alternatively, domains specified using the
tls
field in the spec will also be matched with listeners and their certs will be attached from ACM. This can be used in conjunction with listener host field matching.Example
- attaches certs for
www.example.com
to the ALBapiVersion: extensions/v1beta1 kind: Ingress metadata: namespace: default name: ingress annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' spec: tls: - hosts: - www.example.com rules: - http: paths: - path: /users/* backend: serviceName: user-service servicePort: 80
- single certificate
-
alb.ingress.kubernetes.io/ssl-policy
specifies the Security Policy that should be assigned to the ALB, allowing you to control the protocol and ciphers.Example
alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-1-2017-01
Custom attributes¶
Custom attributes to LoadBalancers and TargetGroups can be controlled with following annotations:
-
alb.ingress.kubernetes.io/load-balancer-attributes
specifies Load Balancer Attributes that should be applied to the ALB.Example
- enable access log to s3
alb.ingress.kubernetes.io/load-balancer-attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=my-access-log-bucket,access_logs.s3.prefix=my-app
- enable deletion protection
alb.ingress.kubernetes.io/load-balancer-attributes: deletion_protection.enabled=true
- enable invalid header fields removal
alb.ingress.kubernetes.io/load-balancer-attributes: routing.http.drop_invalid_header_fields.enabled=true
- enable http2 support
alb.ingress.kubernetes.io/load-balancer-attributes: routing.http2.enabled=true
- set idle_timeout delay to 600 seconds
alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=600
- enable access log to s3
-
alb.ingress.kubernetes.io/target-group-attributes
specifies Target Group Attributes which should be applied to Target Groups.Example
- set the slow start duration to 5 seconds
alb.ingress.kubernetes.io/target-group-attributes: slow_start.duration_seconds=5
- set the deregistration delay to 30 seconds
alb.ingress.kubernetes.io/target-group-attributes: deregistration_delay.timeout_seconds=30
- enable sticky sessions (Please remember to check the target group type to have the appropriate behavior).
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=60
- set load balancing algorithm to least outstanding requests
alb.ingress.kubernetes.io/target-group-attributes: load_balancing.algorithm.type=least_outstanding_requests
- set the slow start duration to 5 seconds
Resource Tags¶
ALB Ingress controller will automatically apply following tags to AWS resources(ALB/TargetGroups/SecurityGroups) created.
kubernetes.io/cluster/${cluster-name}:owned
kubernetes.io/namespace: ${namespace}
kubernetes.io/ingress-name: ${ingress-name}
In addition, you can use annotations to specify additional tags
-
alb.ingress.kubernetes.io/tags
specifies additional tags that will be applied to AWS resources created.Example
alb.ingress.kubernetes.io/tags: Environment=dev,Team=test