-
Notifications
You must be signed in to change notification settings - Fork 207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add KubernetesIngressAddOn for enhanced Ingress Management #989
Merged
shapirov103
merged 41 commits into
aws-quickstart:main
from
Pjv93:add-kubernetes-ingress-addon
Jun 28, 2024
Merged
Changes from 38 commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
96a1075
added kubernetes nginx addon
3a0a9fa
Add KubernetesIngressAddOn for enhanced ingress management
b0ae0e5
added kubernetes nginx test
0d26f2d
added semi-colon
a39f0d7
updated the KubernetesIngressAddOnProps interface to include properti…
18d1121
made the corrections Ela suggested and added the docs for addon along…
29f7ed7
Merge remote-tracking branch 'upstream/main' into add-kubernetes-ingr…
35153df
Resolved merge conflicts
d572c92
Resolved merge conflicts
08b9b79
Merge branch 'aws-quickstart:main' into add-kubernetes-ingress-addon
Pjv93 adf9d3e
Updated Kubernetes-Nginx addon
Pjv93 58505d0
uploaded kubernetes-nginx.md file
Pjv93 02b3604
Update mkdocs.yml
Pjv93 e9cad83
Update index.md
Pjv93 698b52c
Update and rename kubernetes-nginx.md to kubernetes-ingress.md
Pjv93 0f85308
Update index.md
Pjv93 dff5d9e
Recreated folder with proper kubernetes-ingressa and added index.ts
Pjv93 cc8a11e
Update index.ts
Pjv93 1ed7d1e
Update mkdocs.yml
Pjv93 d9c396c
Update index.ts
Pjv93 a4e103c
Delete lib/addons/kubernetes-nginx directory as I have renamed the fi…
Pjv93 1a18751
Update mkdocs.yml added kubeshark to resolve confilct
Pjv93 6d8aa04
Update package.json to resolve conflicts
Pjv93 ef31d19
updated mkdocs.yml file
837fa61
resolved conflicts
79c0311
renamed test file to kubernetes-ingress.test.ts
fb899b2
removed test files
59be4fb
resolved conflicts
ba29239
modified file references from kubernetes-ingress to ingress-nginx.md
9f671f2
Merge branch 'aws-quickstart:main' into add-kubernetes-ingress-addon
Pjv93 1f077e8
Merge branch 'aws-quickstart:main' into add-kubernetes-ingress-addon
Pjv93 e554ae2
Update index.ts - corrected ingress addon name and removed params
Pjv93 e58fa7c
Update index.ts added ingress-nginx
Pjv93 f89aad8
added ingress-nginx.md to mkdocs.yml
6f3a6b9
removed kubernetesNginxAddOn references to IngressNginxAddOn
eb528fa
removed kubernetes-nginx conflict
e407116
Merge remote-tracking branch 'upstream/main' into add-kubernetes-ingr…
6ad6bb0
updated title to Ingress Nginx Addon
0442bfa
modified ingress name from nginx to ingress-nginx
2c1ceb2
added semi-colon to resolve lint warning
14b3b4a
added ClusterIP value to blueprint-construct file
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,259 @@ | ||
# Ingress NGINX Add-on | ||
|
||
This add-on installs [Ingress Nginx Controller](https://kubernetes.github.io/ingress-nginx) on Amazon EKS. Kubernetes NGINX ingress controller uses NGINX as a reverse proxy and load balancer. | ||
|
||
Other than handling Kubernetes ingress objects, this ingress controller can facilitate multi-tenancy and segregation of workload ingresses based on host name (host-based routing) and/or URL Path (path-based routing). | ||
|
||
***IMPORTANT***: | ||
This add-on depends on [AWS Load Balancer Controller](aws-load-balancer-controller.md) Add-on in order to enable NLB support. | ||
|
||
***AWS Load Balancer Controller add-on must be present in add-on array*** and ***must be in add-on array before the NGINX ingress controller add-on*** for it to work, as shown in below example. Otherwise will run into error `Assertion failed: Missing a dependency for AwsLoadBalancerControllerAddOn`. | ||
|
||
## Usage | ||
|
||
```typescript | ||
import 'source-map-support/register'; | ||
import * as cdk from 'aws-cdk-lib'; | ||
import * as blueprints from '@aws-quickstart/eks-blueprints'; | ||
|
||
const app = new cdk.App(); | ||
|
||
const externalDnsHostname = ...; | ||
const awsLbControllerAddOn = new blueprints.addons.AwsLoadBalancerControllerAddOn(); | ||
const IngressNginxAddOn = new blueprints.addons.IngressNginxAddOn({ externalDnsHostname }); | ||
const addOns: Array<blueprints.ClusterAddOn> = [ awsLbControllerAddOn, IngressNginxAddOn ]; | ||
|
||
const blueprint = blueprints.EksBlueprint.builder() | ||
.version("auto") | ||
.addOns(...addOns) | ||
.build(app, 'my-stack-name'); | ||
``` | ||
|
||
To validate that the installation is successful, run the following command: | ||
|
||
```bash | ||
$ kubectl get po -n kube-system | ||
NAME READY STATUS RESTARTS AGE | ||
k8s-ingress-ingress-nginx-controller-75886597f6-n9qnn 1/1 Running 0 119m 1/1 Running 0 4d10h | ||
``` | ||
|
||
Note that the ingress controller is deployed in the `kube-system` namespace. | ||
|
||
Once deployed, it allows applications to create ingress objects and use host-based routing with external DNS support, if the External DNS Add-on is installed. | ||
|
||
## Configuration | ||
|
||
- `backendProtocol`: Indication for AWS Load Balancer controller with respect to the protocol supported on the load balancer. TCP by default. | ||
- `crossZoneEnabled`: Whether to create a cross-zone load balancer with the service that backs NGINX. | ||
- `internetFacing`: Whether the created load balancer is internet-facing. Defaults to `true` if not specified. An internal load balancer is provisioned if set to `false`. | ||
targetType: `ip` or `instance mode`. Defaults to `ip`, which requires VPC-CNI and has better performance by eliminating a hop through kube-proxy. Instance mode leverages traditional NodePort mode on the instances. | ||
- `externaDnsHostname`: Used in conjunction with the external DNS add-on to handle automatic registration of the service with Route 53. | ||
- `values`: Arbitrary values to pass to the chart as per <https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/> | ||
|
||
## DNS Integration and Routing | ||
|
||
If the [External DNS Add-on](../addons/external-dns.md) is installed, it is possible to configure the Kubernetes NGINX ingress with an external NLB load balancer and leverage wild-card DNS domains (and public certificate) to route external traffic to individual workloads. | ||
|
||
The following example provides support for AWS Load Balancer Controller, External DNS, and Kubernetes NGINX add-ons to enable such routing: | ||
|
||
```typescript | ||
blueprints.EksBlueprint.builder() | ||
// Register hosted zone1 under the name of MyHostedZone1 | ||
.resourceProvider("MyHostedZone1", new blueprints.DelegatingHostedZoneProvider({ | ||
parentDomain: 'myglobal-domain.com', | ||
subdomain: 'dev.myglobal-domain.com', | ||
parentAccountId: parentDnsAccountId, | ||
delegatingRoleName: 'DomainOperatorRole', | ||
wildcardSubdomain: true | ||
})) | ||
.addOns(new blueprints.addons.ExternalDnsAddOn({ | ||
hostedZoneProviders: ["MyHostedZone1"] | ||
})) | ||
.addOns(new blueprints.IngressNginxAddOn({ | ||
internetFacing: true, | ||
backendProtocol: "tcp", | ||
externalDnsHostname: subdomain, | ||
crossZoneEnabled: false | ||
})) | ||
.version("auto") | ||
.build(...); | ||
``` | ||
|
||
Assuming the subdomain in the above example is `dev.my-domain.com` and wildcard is enabled for the external DNS add-on, customers can now create ingress objects for host-based routing. Let's define an ingress object for `team-riker` that is currently deploying the guestbook application with no ingress: | ||
|
||
```yaml | ||
apiVersion: networking.k8s.io/v1 | ||
kind: Ingress | ||
metadata: | ||
annotations: | ||
kubernetes.io/ingress.class: nginx | ||
name: ingress-riker | ||
namespace: team-riker | ||
spec: | ||
rules: | ||
- host: riker.dev.my-domain.com | ||
http: | ||
paths: | ||
- backend: | ||
service: | ||
name: guestbook-ui | ||
port: | ||
number: 80 | ||
path: / | ||
pathType: Prefix | ||
``` | ||
|
||
A similar ingress may be defined for `team-troi`, routing to the workloads deployed by that team: | ||
|
||
```yaml | ||
apiVersion: networking.k8s.io/v1 | ||
kind: Ingress | ||
metadata: | ||
annotations: | ||
kubernetes.io/ingress.class: nginx | ||
name: ingress-troi | ||
namespace: team-troi | ||
spec: | ||
rules: | ||
- host: troi.dev.my-domain.com | ||
http: | ||
paths: | ||
- backend: | ||
service: | ||
name: guestbook-ui | ||
port: | ||
number: 80 | ||
path: / | ||
pathType: Prefix | ||
``` | ||
|
||
After the above ingresses are applied (ideally through a GitOps engine), you can now navigate to the specified hosts respectively: | ||
|
||
`http://riker.dev.my-domain.com` | ||
`http://troi.dev.my-domain.com` | ||
|
||
## TLS Termination and Certificates | ||
|
||
You can configure the Kubernetes NGINX add-on to terminate TLS at the load balancer and supply an ACM certificate through the platform blueprint. | ||
|
||
A certificate can be registered using a named [resource provider](../resource-providers/index.md). | ||
|
||
For convenience, the framework provides a couple of common certificate providers: | ||
|
||
**Import Certificate** | ||
|
||
This case is used when a certificate is already created and you just need to reference it with the blueprint stack: | ||
|
||
```typescript | ||
const myCertArn = ""; | ||
blueprints.EksBlueprint.builder() | ||
.resourceProvider(GlobalResources.Certificate, new ImportCertificateProvider(myCertArn, "cert1-id")) | ||
.addOns(new IngressNginxAddOn({ | ||
certificateResourceName: GlobalResources.Certificate, | ||
externalDnsHostname: 'my.domain.com' | ||
})) | ||
.teams(...) | ||
.version("auto") | ||
.build(app, 'stack-with-cert-provider'); | ||
``` | ||
|
||
**Create Certificate** | ||
|
||
This approach is used when a certificate should be created with the blueprint stack. In this case, the new certificate requires DNS validation, which can be accomplished automatically if the corresponding Route 53 hosted zone is provisioned (either along with the stack or separately) and registered as a resource provider. | ||
|
||
```typescript | ||
blueprints.EksBlueprint.builder() | ||
.resourceProvider(GlobalResources.HostedZone ,new ImportHostedZoneProvider('hosted-zone-id1', 'my.domain.com')) | ||
.resourceProvider(GlobalResources.Certificate, new CreateCertificateProvider('domain-wildcard-cert', '*.my.domain.com', GlobalResources.HostedZone)) // referencing hosted zone for automatic DNS validation | ||
.addOns(new AwsLoadBalancerControllerAddOn()) | ||
// Use hosted zone for External DNS | ||
.addOns(new ExternalDnsAddOn({ hostedZoneResources: [GlobalResources.HostedZone] })) | ||
// Use certificate registered before with IngressNginxAddOn | ||
.addOns(new IngressNginxAddOn({ | ||
certificateResourceName: GlobalResources.Certificate, | ||
externalDnsHostname: 'my.domain.com' | ||
})) | ||
.teams(...) | ||
.version("auto") | ||
.build(app, 'stack-with-resource-providers'); | ||
``` | ||
|
||
## Managing Multiple Ingress Controllers with IngressClasses | ||
|
||
The IngressNginxAddOn leverages the Kubernetes NGINX Ingress Controller, which supports using IngressClasses to avoid conflicts. Here's how you can set up and use IngressClasses to manage multiple Ingress controllers effectively. | ||
|
||
**Using IngressClasses with IngressNginxAddOn** | ||
To deploy multiple instances of the NGINX Ingress controller, grant them control over different IngressClasses and select the appropriate IngressClass using the ingressClassName field in your Ingress resources. The IngressNginxAddOn simplifies this setup by allowing you to define these parameters directly. | ||
|
||
### Add-on Configuration Example** | ||
|
||
```typescript | ||
const IngressNginxAddOn = new blueprints.addons.IngressNginxAddOn({ | ||
crossZoneEnabled: true, | ||
internetFacing: true, | ||
targetType: 'ip', | ||
externalDnsHostname: myDomainName, | ||
certificateResourceName: blueprints.GlobalResources.Certificate, | ||
ingressClassName: 'internal-nginx', | ||
controllerClass: 'k8s.io/internal-ingress-nginx', | ||
electionId: 'ingress-controller-leader-internal' | ||
}); | ||
``` | ||
|
||
**Helm Chart Values** | ||
The add-on configuration sets up the necessary values for the Helm chart: | ||
|
||
```typescript | ||
const values: Values = { | ||
controller: { | ||
service: { | ||
annotations: presetAnnotations | ||
}, | ||
ingressClassResource: { | ||
name: props.ingressClassName || "nginx", | ||
enabled: true, | ||
default: props.isDefaultClass ?? false, | ||
controllerValue: props.controllerClass || "k8s.io/ingress-nginx" | ||
}, | ||
electionID: props.electionId || "ingress-controller-leader" | ||
} | ||
}; | ||
``` | ||
|
||
## Benefits | ||
|
||
- Service Annotations: Customize the Kubernetes Service resource exposing the NGINX ingress controller for better control over AWS integrations. | ||
- Ingress Class Resource: Manage multiple Ingress configurations by specifying different ingress classes, ensuring proper routing and avoiding conflicts. | ||
- Election ID: Ensure high availability and reliability by using a unique election ID for each controller instance, avoiding conflicts between multiple instances. | ||
|
||
## Differences between Kubernetes NGINX Ingress Controller and NGINX Inc. Ingress Controller | ||
|
||
The Kubernetes NGINX Ingress Controller and the NGINX Inc. Ingress Controller both use NGINX, but they have different implementations and configurations: | ||
|
||
1. Repository Source: | ||
|
||
Kubernetes NGINX: Available at [kubernetes/ingress-nginx](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/). | ||
NGINX Inc.: Available at [nginxinc/kubernetes-ingress](https://kubernetes.github.io/ingress-nginx/deploy/). | ||
|
||
1. Configuration and Features: | ||
|
||
Kubernetes NGINX: More commonly used within the Kubernetes community, with extensive community support and documentation. | ||
NGINX Inc.: Provided by NGINX Inc., potentially with enterprise features and different configurations. | ||
|
||
1. Annotations and Settings: | ||
|
||
Kubernetes NGINX: May have different annotations and settings specific to Kubernetes community practices. | ||
NGINX Inc.: May offer additional enterprise-grade features and require different annotations. | ||
|
||
1. Support and Updates: | ||
|
||
Kubernetes NGINX: Community-supported with frequent updates based on community contributions. | ||
NGINX Inc.: Officially supported by NGINX Inc., with potential access to enterprise support and updates. | ||
|
||
## Functionality | ||
|
||
1. Installs Kubernetes NGINX ingress controller | ||
2. Provides convenience options to integrate with AWS Load Balancer Controller to leverage NLB for the load balancer | ||
3. Provides convenience options to integrate with External DNS add-on for integration with Amazon Route 53 | ||
4. Allows configuring TLS termination at the load balancer provisioned with the add-on | ||
5. Supports [standard helm configuration options](./index.md#standard-helm-add-on-configuration-options) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this file checked in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might have been a mistake as I was testing my own main.ts file and reverted it to the original file. Theres no difference. I think the blank line in line 12 was removed in the process.