diff --git a/src/.dockerignore b/.dockerignore similarity index 100% rename from src/.dockerignore rename to .dockerignore diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0f122d75..2f853102 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -35,4 +35,3 @@ jobs: - name: make test run: make test - working-directory: ./src diff --git a/.gitignore b/.gitignore index aaf22e20..e8c5b1d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -### Go ### # Binaries for programs and plugins *.exe *.exe~ @@ -6,17 +5,20 @@ *.so *.dylib -# Test binary, built with `go test -c` -*.test +# Tools directory. +bin/ + +# Generated symlinks. +cmd/**/kodata/ # Output of the go coverage tool, specifically when used with LiteIDE *.out -.idea/ -# Output of the go build for the cmd binary -/node-termination-handler +# Kubernetes Generated files - skip generated files, except for vendored files +!vendor/**/zz_generated.* -### Go Patch ### -/vendor/ -/Godeps/ -/build/ +# Editor and IDE paraphernalia +.idea +*.swp +*.swo +*~ diff --git a/BUILD.md b/BUILD.md deleted file mode 100644 index d35a96b2..00000000 --- a/BUILD.md +++ /dev/null @@ -1,73 +0,0 @@ -# Setup Development Environment - -## Clone the repo - -```sh -git clone --branch v2 https://github.com/aws/aws-node-termination-handler.git -cd aws-node-termination-handler -``` - -## Set environment variables - -```sh -export AWS_REGION= -export AWS_ACCOUNT_ID= -export CLUSTER_NAME= -``` - -## Create Image Repositories - -```sh -aws ecr create-repository \ - --repository-name nthv2/controller \ - --image-scanning-configuration scanOnPush=true \ - --region "${AWS_REGION}" - -aws ecr create-repository \ - --repository-name nthv2/webhook \ - --image-scanning-configuration scanOnPush=true \ - --region "${AWS_REGION}" - -export KO_DOCKER_REPO="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/nthv2" - -./scripts/docker-login-ecr.sh -``` - -## Create an EKS Cluster - -```sh -envsubst src/resources/eks-cluster.yaml.tmpl | eksctl create cluster -f - -``` - -### Create the Controller IAM Role - -```sh -aws cloudformation deploy \ - --template-file src/resources/controller-iam-role.yaml \ - --stack-name "nthv2-${CLUSTER_NAME}" \ - --capabilities CAPABILITY_NAMED_IAM \ - --parameter-overrides "ClusterName=${CLUSTER_NAME}" - -eksctl create iamserviceaccount \ - --cluster "${CLUSTER_NAME}" \ - --name nthv2 \ - --namespace nthv2 \ - --role-name "${CLUSTER_NAME}-nthv2" \ - --attach-policy-arn "arn:aws:iam::${AWS_ACCOUNT_ID}:policy/Nthv2ControllerPolicy-${CLUSTER_NAME}" \ - --role-only \ - --approve - -export NTHV2_IAM_ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/${CLUSTER_NAME}-nthv2 -``` - -## Build and deploy controller to Kubernetes cluster - -```sh -make apply -``` - -## Remove deployed controller from Kubernetes cluster - -```sh -make delete -``` \ No newline at end of file diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 00000000..003f75bd --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,160 @@ +# Setup Development Environment + +## 1. Clone the repo + +```sh +git clone --branch v2 https://github.com/aws/aws-node-termination-handler.git nthv2 +cd nthv2 +``` + +## 2. Specify an EKS Cluster + +*Tip:* Several steps in this guide, and utility scripts, use environment variables. Saving these environment variables in a file, or using a shell extension that manages sets of environment variables, will make it easier to restore your development environment in a new shell. + +```sh +export CLUSTER_NAME= +export AWS_REGION= +``` + +### 2.1. (Optional) Create the EKS Cluster + +Skip this set if you already have an EKS cluster. + +```sh +envsubst +export QUEUE_STACK_NAME="${INFRASTRUCTURE_STACK_NAME}-queue-${QUEUE_NAME}" + +aws cloudformation deploy \ + --template-file resources/queue-infrastructure.yaml \ + --stack-name "${QUEUE_STACK_NAME}" \ + --parameter-overrides \ + ClusterName="${CLUSTER_NAME}" \ + QueueName="${QUEUE_NAME}" +``` + +Resources created: + +* `Queue` - SQS Queue that will receive messages from EventBridge +* `AutoScalingTerminationRule` - EventBridge Rule to route instance-terminate lifecycle action messages from Auto Scaling Groups to `Queue` +* `RebalanceRecommendationRule` - EventBridge Rule to route rebalance recommendation messages from EC2 to `Queue` +* `ScheduledChangeRule` - EventBridge Rule to route scheduled change messages from AWS Health to `Queue` +* `SpotInterruptionRule` - EventBridge Rule to route EC2 Spot interruption notice messages from EC2 to `Queue` +* `StateChangeRule` - EventBridgeRule to route state change messages from EC2 to `Queue` + +## 4. Connect Infrastructure to EKS Cluster + +```sh +export CLUSTER_NAMESPACE= +export SERVICE_ACCOUNT_NAME="nth-${CLUSTER_NAME}-serviceaccount" + +eksctl create iamserviceaccount \ + --cluster "${CLUSTER_NAME}" \ + --namespace "${CLUSTER_NAMESPACE}" \ + --name "${SERVICE_ACCOUNT_NAME}" \ + --role-name "${SERVICE_ACCOUNT_NAME}" \ + --attach-policy-arn $(./scripts/get-cfn-stack-output.sh "${INFRASTRUCTURE_STACK_NAME}" ServiceAccountPolicyARN) \ + --role-only \ + --approve + +export SERVICE_ACCOUNT_ROLE_ARN=$(eksctl get iamserviceaccount \ + --cluster "${CLUSTER_NAME}" \ + --namespace "${CLUSTER_NAMESPACE}" \ + --name "${SERVICE_ACCOUNT_NAME}" \ + --output json | \ + jq -r '.[0].status.roleARN') +``` + +## 5. Configure and Login to Image Repository + +```sh +export KO_DOCKER_REPO=$(./scripts/get-cfn-stack-output.sh "${DEV_INFRASTRUCTURE_STACK_NAME}" RepositoryBaseURI) + +./scripts/docker-login-ecr.sh +``` + +## 6. Build and deploy controller to EKS cluster + +```sh +make apply +``` + +### 6.1. (Optional) Providing additional Helm values + +The `apply` target sets some Helm chart values for you based on environment variables. To set additional Helm values use the `HELM_OPTS` make argument. For example: + +```sh +make HELM_OPTS='--set logging.level=debug' apply +``` + +## 7. Define and deploy a Terminator to EKS cluster + +```sh +export TERMINATOR_NAME= +export QUEUE_URL=$(./scripts/get-cfn-stack-output.sh "${QUEUE_STACK_NAME}" QueueURL) + +envsubst terminator-${TERMINATOR_NAME}.yaml + +kubectl apply -f terminator-${TERMINATOR_NAME}.yaml +``` + +If you do not want to use `envsubst` you can copy the template file and substitute the referenced values. + +## 8. Remove deployed controller from EKS cluster + +```sh +make delete +``` + +# Tear down Development Environment + +```sh +make delete + +eksctl delete cluster --name "${CLUSTER_NAME}" + +aws cloudformation delete-stack --stack-name "${QUEUE_STACK_NAME}" + +./scripts/clear-image-repo.sh "$(./scripts/get-cfn-stack-output.sh ${DEV_INFRASTRUCTURE_STACK_NAME} ControllerRepositoryName)" +./scripts/clear-image-repo.sh "$(./scripts/get-cfn-stack-output.sh ${DEV_INFRASTRUCTURE_STACK_NAME} WebhookRepositoryName)" +aws cloudformation delete-stack --stack-name "${DEV_INFRASTRUCTURE_STACK_NAME}" + +aws cloudformation delete-stack --stack-name "${INFRASTRUCTURE_STACK_NAME}" +``` diff --git a/src/Dockerfile b/Dockerfile similarity index 100% rename from src/Dockerfile rename to Dockerfile diff --git a/src/Makefile b/Makefile similarity index 96% rename from src/Makefile rename to Makefile index bb5c9faf..19b59eae 100644 --- a/src/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CONTROLLER_GEN = $(BIN_DIR)controller-gen KO = $(BIN_DIR)/ko SETUP_ENVTEST = $(BIN_DIR)/setup-envtest GINKGO = $(BIN_DIR)/ginkgo -HELM_BASE_OPTS ?= --set serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn=${NTHV2_IAM_ROLE_ARN} +HELM_BASE_OPTS ?= --set aws.region=${AWS_REGION},serviceAccount.name=${SERVICE_ACCOUNT_NAME},serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn=${SERVICE_ACCOUNT_ROLE_ARN} GINKGO_BASE_OPTS ?= --coverpkg $(shell head -n 1 $(PROJECT_DIR)/go.mod | cut -s -d ' ' -f 2)/pkg/... KODATA = \ cmd/controller/kodata/HEAD \ diff --git a/src/PROJECT b/PROJECT similarity index 100% rename from src/PROJECT rename to PROJECT diff --git a/README.md b/README.md index 704e35d9..d78bc23f 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,6 @@

Gracefully handle EC2 instance shutdown within Kubernetes

-### Community Meeting -NTH community meeting is hosted on a monthly cadence. Everyone is welcome to participate! -* **When:** first Tuesday of every month from 9:00-9:30AM PST | [Calendar Event (ics)](https://raw.githubusercontent.com/aws/aws-node-termination-handler/main/assets/nth-community-meeting.ics) -* **Where:** [Chime meeting bridge](https://chime.aws/6502066216) - - ## Project Summary This project ensures that the Kubernetes control plane responds appropriately to events that can cause your EC2 instance to become unavailable, such as [EC2 maintenance events](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html), [EC2 Spot interruptions](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html), [ASG Scale-In](https://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroupLifecycle.html#as-lifecycle-scale-in), [ASG AZ Rebalance](https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-benefits.html#AutoScalingBehavior.InstanceUsage), and EC2 Instance Termination via the API or Console. If not handled, your application code may not stop gracefully, take longer to recover full availability, or accidentally schedule work to nodes that are going down. @@ -23,20 +17,15 @@ This project ensures that the Kubernetes control plane responds appropriately to - Webhook feature to send shutdown or restart notification messages - Unit & Integration Tests -## Installation and Configuration - -TBD - -### Installation and Configuration - -TBD +## Getting Started ### Infrastructure Setup TBD -## Building -For build instructions please consult [BUILD.md](./BUILD.md). +### Installation and Configuration + +For a full list of inputs see the Helm chart [README.md](./charts/aws-node-termination-handler-2/README.md). ## Metrics @@ -50,6 +39,7 @@ TBD ## Contributing Contributions are welcome! Please read our [guidelines](https://github.com/aws/aws-node-termination-handler/blob/main/CONTRIBUTING.md) and our [Code of Conduct](https://github.com/aws/aws-node-termination-handler/blob/main/CODE_OF_CONDUCT.md) +To setup a development environment see the instructions in [DEVELOPMENT.md](./DEVELOPMENT.md). + ## License This project is licensed under the Apache-2.0 License. - diff --git a/src/api/v1alpha1/groupversion_info.go b/api/v1alpha1/groupversion_info.go similarity index 100% rename from src/api/v1alpha1/groupversion_info.go rename to api/v1alpha1/groupversion_info.go diff --git a/src/api/v1alpha1/terminator_logging.go b/api/v1alpha1/terminator_logging.go similarity index 100% rename from src/api/v1alpha1/terminator_logging.go rename to api/v1alpha1/terminator_logging.go diff --git a/src/api/v1alpha1/terminator_types.go b/api/v1alpha1/terminator_types.go similarity index 100% rename from src/api/v1alpha1/terminator_types.go rename to api/v1alpha1/terminator_types.go diff --git a/src/api/v1alpha1/terminator_validation.go b/api/v1alpha1/terminator_validation.go similarity index 100% rename from src/api/v1alpha1/terminator_validation.go rename to api/v1alpha1/terminator_validation.go diff --git a/src/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go similarity index 100% rename from src/api/v1alpha1/zz_generated.deepcopy.go rename to api/v1alpha1/zz_generated.deepcopy.go diff --git a/assets/nth-community-meeting.ics b/assets/nth-community-meeting.ics deleted file mode 100644 index e33306b2..00000000 --- a/assets/nth-community-meeting.ics +++ /dev/null @@ -1,49 +0,0 @@ -BEGIN:VCALENDAR -CALSCALE:GREGORIAN -VERSION:2.0 -X-WR-CALNAME:AWS Node Termination Handler Community Meeting -METHOD:PUBLISH -PRODID:-//Apple Inc.//macOS 11.6.2//EN -BEGIN:VTIMEZONE -TZID:America/Chicago -BEGIN:DAYLIGHT -TZOFFSETFROM:-0600 -RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU -DTSTART:20070311T020000 -TZNAME:CDT -TZOFFSETTO:-0500 -END:DAYLIGHT -BEGIN:STANDARD -TZOFFSETFROM:-0500 -RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU -DTSTART:20071104T020000 -TZNAME:CST -TZOFFSETTO:-0600 -END:STANDARD -END:VTIMEZONE -BEGIN:VEVENT -TRANSP:OPAQUE -DTEND;TZID=America/Chicago:20220104T113000 -LAST-MODIFIED:20220104T153156Z -UID:4693991B-94C2-4E48-A18C-C8DF1082D77C -DTSTAMP:20220104T152914Z -DESCRIPTION:==============Conference Bridge Information==============\nY - ou have been invited to an online meeting\, powered by Amazon Chime.\n\n - Chime meeting ID: 6502066216\n\nJoin via Chime clients (manually): Selec - t "Meetings > Join a Meeting"\, and enter 6502066216\n\nJoin via Chime c - lients (auto-call): If you invite auto-call as attendee\, Chime will cal - l you when the meeting starts\, select "Answer"\n\nJoin via browser scre - en share: https://chime.aws/6502066216\n\nJoin via phone (US): +1-929-43 - 2-4463\,\,\,6502066216#\n\nJoin vi - a phone (US toll-free): +1-855-552-4463\,\,\,6502066216#\n\nInternational dial-in: https://chime.aws/diali - nnumbers/\n\nIn-room video system: Ext: 62000\, Meeting PIN: 6502066216# - \n\n================================================= -SEQUENCE:0 -X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC -DTSTART;TZID=America/Chicago:20220104T110000 -SUMMARY:AWS Node Termination Handler Community Meeting -CREATED:20220104T152821Z -RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=1TU -END:VEVENT -END:VCALENDAR diff --git a/src/charts/aws-node-termination-handler-2/Chart.yaml b/charts/aws-node-termination-handler-2/Chart.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/Chart.yaml rename to charts/aws-node-termination-handler-2/Chart.yaml diff --git a/charts/aws-node-termination-handler-2/README.md b/charts/aws-node-termination-handler-2/README.md new file mode 100644 index 00000000..9f74ca32 --- /dev/null +++ b/charts/aws-node-termination-handler-2/README.md @@ -0,0 +1,72 @@ +# AWS Node Termination Handler + +AWS Node Termination Handler Helm chart for Kubernetes. For more information on this project see the project repo at [github.com/aws/aws-node-termination-handler](https://github.com/aws/aws-node-termination-handler). + +## Prerequisites + +- _Kubernetes_ >= 1.16 + +## Installing the Chart + +Before you can install the chart you will need to add the `eks` repo to [Helm](https://helm.sh/). + +```shell +helm repo add eks https://aws.github.io/eks-charts/ +``` + +### Configuration + +* `annotations` - Annotation names and values to add to objects in the Helm release. Default: `{}`. +* `aws.region` - AWS region name (e.g. "us-east-1") to use when making API calls. Default: `""`. +* `controller.env` - List of environment variables to set in the controller container. See [core/v1 Pod.spec.containers.env](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#container-v1-core) Default: `[]`. +* `controller.image` - Image repository for the controller. +* `controller.logLevel` - Override the global logging level for the controller container. Default: `""`. +* `controller.resources` - Resource requests and limits for controller container. See [core/v1 ResourceRequests](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#resourcerequirements-v1-core) for further information. Default: `{"requests":{"cpu": 1, "memory": "1Gi"}, "limits":{"cpu": 1, "memory": "1Gi"}}` +* `controller.securityContext` - Controller container security context configuration. See [core/v1 Pod.spec.securityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podsecuritycontext-v1-core) for further information. Default: `{}`. +* `fullnameOverride` - Override the Helm release name. Name will be truncated if longer than 63 characters. Default is generated from the release name and chart name. +* `imagePullPolicy` - Policy for when to pull images. See [core/v1 Container.imagePullPolicy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#container-v1-core) for further information. Default: `"IfNotPresent"`. +* `imagePullSecrets` - List of secrets to use when pulling images. See [apps/v1 Deployment.spec.template.spec.imagePullSecrets](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core) for further information. Default: `[]`. +* `labels` - Label names and values to add to objects in the Helm release. Default: `{}`. +* `logging.development` - Enable "debug mode" in logging module. May be useful during development. Default: `false`. +* `logging.disableCaller` - Disable annotating log messages with calling function's file name and line number. Default: `true`. +* `logging.disableStacktrace` - Disable stacktrace captures for all message levels. Default: `true`. +* `logging.encoding` - Logging module encoding mode. Possible values: `console`, `json`. Default: `console`. +* `logging.encoderConfig.callerKey` - Name of the caller field. Default: `"caller"`. +* `logging.encoderConfig.levelEncoder` - Level encoder name. Possible values: `capital`, `capitalColor`, `color`; otherwise the level name will be encoded as lowercase. Default: `"capital"`. +* `logging.encoderConfig.levelKey` - Name of the level field. Default: `"level"`. +* `logging.encoderConfig.messageKey` - Name of the message field. Default: `"message"`. +* `logging.encoderConfig.nameKey` - Name of the logger name field. Default: `"logger"`. +* `logging.encoderConfig.stacktraceKey` - Name of the stacktrace field. Default: `"stacktrace"`. +* `logging.encoderConfig.timeEncoder` - Time encoder name. Possible values: `iso8601`, `millis`, `nano`, `rfc3339`, `rfc3339nano`; otherwise the time will be encoded in epoch format. Default: `"iso8601"`. +* `logging.encoderConfig.timeKey` - Name of the time field. Default: `"time"`. +* `logging.errorOutputPaths` - List of paths to output internal errors from the logging module. Possible values: `stderr`, `stdout`; otherwise a valid file path. Default: `["stderr"]`. +* `logging.level` - Minimum message level to include in the log. Possible values: `debug`, `info`, `warn`, `error`, `panic`, `fatal`. Default: `info`. +* `logging.outputPaths` - List of additional output paths. Possible values: `stderr`, `stdout`; otherwise a valid file path. Default: `["stdout"]`. +* `logging.sampling.initial` - Limit of initial messages per second to accept. Default: `100`. +* `logging.sampling.thereafter` - Limit of messages per second to accept after initial phase. Default: `100`. +* `nameOverride` - Override the Helm chart name. Name will be truncated if longer than 63 characters. Default: `.Chart.Name`. +* `pod.annotations` - Annotation to apply to deployed pod. Default: `{}`. +* `pod.hostNetwork` - Request host network for pod. See [core/v1 Pod.spec.hostNetwork](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core) for futher information. Default: `false`. +* `pod.labels` - Labels to apply to deployed pod. Default: `{}`. +* `pod.nodeSelector` - Node selector labels. Default: `{"kubernetes.io/os": "linux"}` +* `pod.priorityClassName` - Pod priority class. See [core/v1 Pod.spec.priorityClassName](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core) for futher information. Default: `"system-cluster-critical"`. +* `pod.replicas` - Number of instances to create. Default: `1`. +* `pod.securityContext` - Pod security context configuration. See documentation for [core/v1 Pod.spec.securityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podsecuritycontext-v1-core) for available properties. Default: `{"fsGroup": 1000}`. +* `pod.updateStrategy` - Deployment update strategy configuration. See documentation for [apps/v1 Deployment.spec.strategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#deploymentstrategy-v1-apps) for available properties. Default: `{"type": "Recreate"}`. +* `rbac.create` - Enable creation of RBAC objects. Helm release may fail is RBAC objects already exist. Default: `true`. +* `serviceAccount.annotations` - Annotation names and values to add to service account. Default: `{}`. +* `serviceAccount.create` - Enable creation of service account. Helm release may fail if service account already exists. Default: `true`. +* `serviceAccount.name` - Name of the service account. If `serviceAccount.create` is enabled then the default will be generated from the release name and chart name. If `serviceAccount.create` is disabled then the default is `"default"`. +* `terminator.defaults.drain.force` - Default value of `Terminator`'s `spec.drain.force` property. Default: `true`. +* `terminator.defaults.drain.gracePeriodSeconds` - Default value of `Terminator`'s `spec.drain.gracePeriodSeconds` property. Default: `-1`. +* `terminator.defaults.drain.ignoreAllDaemonSets` - Default value of `Terminator`'s `spec.drain.ignoreAllDaemonSets` property. Default: `true`. +* `terminator.defaults.drain.deleteEmptyDirData` - Default value of `Terminator`'s `spec.drain.deleteEmptyDirData` property. Default: `true`. +* `terminator.defaults.drain.timeoutSeconds` - Default value of `Terminator`'s `spec.drain.timeoutSeconds` property. Default: `120`. +* `terminator.defaults.webhook.headers` - Default value of `Terminator`'s `spec.webhook.headers` property. Default: `[{"name": "Content-Type", "value": "application/json"}]`. +* `terminator.defaults.webhook.template` - Default value of `Terminator`'s `spec.webhook.template` property. Default: `'{"text":"[NTH][Instance Interruption] EventID: {{ .EventID }} - Kind: {{ .Kind }} - Instance: {{ .InstanceID }} - Node: {{ .NodeName }} - Start Time: {{ .StartTime }}"}'`. +* `webhook.env` - List of environment variables to set in the webhook container. See [core/v1 Pod.spec.containers.env](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#container-v1-core) Default: `[]`. +* `webhook.image` - Image repository for the webhook controller. +* `webhook.logLevel` - Override the global logging level for the webhook container. Default: `""`. +* `webhook.port` - List on port. Default: `8443`. +* `webhook.resources` - Resource requests and limits for webhook container. See [core/v1 ResourceRequests](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#resourcerequirements-v1-core) for further information. Default: `{"requests":{"cpu": 1, "memory": "1Gi"}, "limits":{"cpu": 1, "memory": "1Gi"}}` +* `webhook.securityContext` - Controller container security context configuration. See [core/v1 Pod.spec.securityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podsecuritycontext-v1-core) for further information. Default: `{}`. diff --git a/src/charts/aws-node-termination-handler-2/templates/_helpers.tpl b/charts/aws-node-termination-handler-2/templates/_helpers.tpl similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/_helpers.tpl rename to charts/aws-node-termination-handler-2/templates/_helpers.tpl diff --git a/src/charts/aws-node-termination-handler-2/templates/clusterrole.yaml b/charts/aws-node-termination-handler-2/templates/clusterrole.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/clusterrole.yaml rename to charts/aws-node-termination-handler-2/templates/clusterrole.yaml diff --git a/src/charts/aws-node-termination-handler-2/templates/clusterrole_binding.yaml b/charts/aws-node-termination-handler-2/templates/clusterrole_binding.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/clusterrole_binding.yaml rename to charts/aws-node-termination-handler-2/templates/clusterrole_binding.yaml diff --git a/src/charts/aws-node-termination-handler-2/templates/configmap_logging.yaml b/charts/aws-node-termination-handler-2/templates/configmap_logging.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/configmap_logging.yaml rename to charts/aws-node-termination-handler-2/templates/configmap_logging.yaml diff --git a/src/charts/aws-node-termination-handler-2/templates/deployment.yaml b/charts/aws-node-termination-handler-2/templates/deployment.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/deployment.yaml rename to charts/aws-node-termination-handler-2/templates/deployment.yaml diff --git a/src/charts/aws-node-termination-handler-2/templates/node.k8s.aws_terminators.yaml b/charts/aws-node-termination-handler-2/templates/node.k8s.aws_terminators.yaml similarity index 89% rename from src/charts/aws-node-termination-handler-2/templates/node.k8s.aws_terminators.yaml rename to charts/aws-node-termination-handler-2/templates/node.k8s.aws_terminators.yaml index be1f33ec..f2d61e2f 100644 --- a/src/charts/aws-node-termination-handler-2/templates/node.k8s.aws_terminators.yaml +++ b/charts/aws-node-termination-handler-2/templates/node.k8s.aws_terminators.yaml @@ -37,7 +37,7 @@ spec: type: object properties: matchLabels: - description: Filter nodes by label that will be acted upon. + description: Action will only be taken if the target node has all the matching labels and values. type: object additionalProperties: type: string @@ -56,43 +56,35 @@ spec: * QueueURL is a required field type: string drain: - description: TBD + description: Configuration for the cordon and drain actions. type: object properties: force: - description: TBD + description: Enable termination of pods without a controller. type: boolean {{- with .Values.terminator.defaults.drain.force }} default: {{ . }} {{- end }} gracePeriodSeconds: - description: | - Time to wait for a pod to terminate. - - * A value of 0 will cause pods to be deleted immediately. - - * A negative value will use the pod's terminationGracePeriodSeconds. + description: Wait time for pods to exit. If negative then the pod's configured gracetime will be used. type: integer {{- with .Values.terminator.defaults.drain.gracePeriodSeconds }} default: {{ . }} {{- end }} ignoreAllDaemonSets: - description: Do not terminate pods managed by a daemon set. + description: Enable ignoring pods managed by a DaemonSet. type: boolean {{- with .Values.terminator.defaults.drain.ignoreAllDaemonSets }} default: {{ . }} {{- end }} deleteEmptyDirData: - description: Terminate pods using emptyDir. The local data will be deleted. + description: Enable termination of pods with local data that will be deleted. type: boolean {{- with .Values.terminator.defaults.drain.deleteEmptyDirData }} default: {{ . }} {{- end }} timeoutSeconds: - description: | - Time to wait for a "delete" command to complete. - - * A value of 0 means to wait indefinitly. + description: Wait time before failing the action. If zero, wait forever. type: integer {{- with .Values.terminator.defaults.drain.timeoutSeconds }} default: {{ . }} diff --git a/src/charts/aws-node-termination-handler-2/templates/role.yaml b/charts/aws-node-termination-handler-2/templates/role.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/role.yaml rename to charts/aws-node-termination-handler-2/templates/role.yaml diff --git a/src/charts/aws-node-termination-handler-2/templates/role_binding.yaml b/charts/aws-node-termination-handler-2/templates/role_binding.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/role_binding.yaml rename to charts/aws-node-termination-handler-2/templates/role_binding.yaml diff --git a/src/charts/aws-node-termination-handler-2/templates/secret_webhook_cert.yaml b/charts/aws-node-termination-handler-2/templates/secret_webhook_cert.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/secret_webhook_cert.yaml rename to charts/aws-node-termination-handler-2/templates/secret_webhook_cert.yaml diff --git a/src/charts/aws-node-termination-handler-2/templates/service.yaml b/charts/aws-node-termination-handler-2/templates/service.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/service.yaml rename to charts/aws-node-termination-handler-2/templates/service.yaml diff --git a/src/charts/aws-node-termination-handler-2/templates/serviceaccount.yaml b/charts/aws-node-termination-handler-2/templates/serviceaccount.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/serviceaccount.yaml rename to charts/aws-node-termination-handler-2/templates/serviceaccount.yaml diff --git a/src/charts/aws-node-termination-handler-2/templates/webhooks.yaml b/charts/aws-node-termination-handler-2/templates/webhooks.yaml similarity index 100% rename from src/charts/aws-node-termination-handler-2/templates/webhooks.yaml rename to charts/aws-node-termination-handler-2/templates/webhooks.yaml diff --git a/charts/aws-node-termination-handler-2/values.yaml b/charts/aws-node-termination-handler-2/values.yaml new file mode 100644 index 00000000..caf8f18a --- /dev/null +++ b/charts/aws-node-termination-handler-2/values.yaml @@ -0,0 +1,194 @@ +# Annotation names and values to add to objects in the Helm release. +annotations: {} + +aws: + # AWS region name (e.g. "us-east-1") to use when making API calls. + region: "" + +controller: + # Environment variables. + env: [] + # Example: + # - name: AWS_REGION + # . value: eu-west-1 + + # Image to deploy. + image: "public.ecr.aws/aws-node-termination-handler:v2.0.0-0.1" + + # Override global logging level. + logLevel: "" + + # Additional security context configuration for the controller pod. + securityContext: {} + + # Resources for the controller pod. + resources: + requests: + cpu: 1 + memory: 1Gi + limits: + cpu: 1 + memory: 1Gi + +# Override the Helm release name. Name will be truncated if longer than 63 characters. +fullnameOverride: "" + +# Policy on when to pull image. +# See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#container-v1-core +imagePullPolicy: IfNotPresent + +# Secrets for accessing image. +# See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core +imagePullSecrets: [] + +# Label names and values to add to objects in the Helm release. +labels: {} + +# Global logging configuration. +logging: + # Enable "debug mode" in logging module. May be useful during development. + development: false + # Disable annotating log messages with calling function's file name and line number. + disableCaller: true + # Disable stacktrace captures for all message levels. + disableStacktrace: true + # Logging module encoding mode. Possible values: `console`, `json`. + encoding: console + encoderConfig: + # Name of the caller field. + callerKey: caller + # Level encoder name. Possible values: `capital`, `capitalColor`, `color`; otherwise the level name + # will be encoded as lowercase. + levelEncoder: capital + # Name of the level field. + levelKey: level + # Name of the message field. + messageKey: message + # Name of the name field. + nameKey: logger + # Name of the stacktrace field. + stacktraceKey: stacktrace + # Time encoder name. Possible values: `iso8601`, `millis`, `nano`, `rfc3339`, `rfc3339nano`; + # otherwise the time will be encoded in epoch format. + timeEncoder: iso8601 + # Name of the time field. + timeKey: time + # List of paths to output internal errors from the logging module. Possible values: `stderr`, `stdout`; + # otherwise a valid file path. + errorOutputPaths: + - stderr + # Minimum message level to include in the log. Possible values: `debug`, `info`, `warn`, `error`, `panic`, + # `fatal`. + level: info + # List of additional output paths. Possible values: `stderr`, `stdout`; otherwise a valid file path. + outputPaths: + - stdout + sampling: + # Limit of initial messages per second to accept. + initial: 100 + # Limit of messages per second to accept after initial phase. + thereafter: 100 + +# Override the Helm chart name. Name will be truncated if longer than 63 characters. +nameOverride: "" + +pod: + # Annotations to apply to deployed pods. + annotations: {} + + # Request host network for pod. + hostNetwork: false + + # Labels to apply to deployed pods. + labels: {} + + # Node selector labels. + nodeSelector: + kubernetes.io/os: linux + + # Pod priority class. + # See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core + priorityClassName: "system-cluster-critical" + + # Number of instances to create. + replicas: 1 + + # Pod security group configuration. + # See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podsecuritycontext-v1-core + securityContext: + fsGroup: 1000 + + # Deployment update strategy configuration. + # See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#deploymentstrategy-v1-apps + updateStrategy: + type: Recreate + +rbac: + # Create the RBAC objects. May fail if RBAC objects already exist. + create: true + +serviceAccount: + # Create the service account. May fail if service account already exists. + create: true + + # Name of service account. If empty then a name will be generated. + name: "" + + # Annotations to add to the service account. + annotations: {} + # "eks.amazonaws.com/role-arn": + +terminator: + defaults: + drain: + # Terminate pods that do not have a controller. + force: true + # Duration to wait for each pod to terminate. If negative then the pod's grace period will be used. + gracePeriodSeconds: -1 + # Do not terminate pods managed by a DaemonSet. + ignoreAllDaemonSets: true + # Terminate pods that have local data that will be deleted. + deleteEmptyDirData: true + # Duration to wait before giving up. If 0, then wait forever. + timeoutSeconds: 120 + webhook: + # List of HTTP heads to include in webhook requests. + headers: + - name: Content-Type + value: application/json + # Template used to generate webhook request body. The template may reference: + # * EventID + # * Kind + # * InstanceID + # * NodeName + # * StartTime + # See https://pkg.go.dev/text/template documentation for template format examples and explanation. + template: '{"text":"[NTH][Instance Interruption] EventID: {{ .EventID }} - Kind: {{ .Kind }} - Instance: {{ .InstanceID }} - Node: {{ .NodeName }} - Start Time: {{ .StartTime }}"}' + +webhook: + # Environment variables. + env: [] + # Example: + # - name: AWS_REGION + # . value: eu-west-1 + + # Image to deploy. + image: "public.ecr.aws/aws-node-termination-handler:v2.0.0-0.1" + + # Override global logging level. + logLevel: "" + + # Listen on port. + port: 8443 + + # Resources for the webhook pod. + resources: + requests: + cpu: 100m + memory: 50Mi + limits: + cpu: 100m + memory: 50Mi + + # Additional security context configuration for the webhook pod. + securityContext: {} diff --git a/src/cmd/controller/main.go b/cmd/controller/main.go similarity index 100% rename from src/cmd/controller/main.go rename to cmd/controller/main.go diff --git a/src/cmd/webhook/main.go b/cmd/webhook/main.go similarity index 100% rename from src/cmd/webhook/main.go rename to cmd/webhook/main.go diff --git a/src/go.mod b/go.mod similarity index 100% rename from src/go.mod rename to go.mod diff --git a/src/go.sum b/go.sum similarity index 100% rename from src/go.sum rename to go.sum diff --git a/src/hack/boilerplate.go.txt b/hack/boilerplate.go.txt similarity index 100% rename from src/hack/boilerplate.go.txt rename to hack/boilerplate.go.txt diff --git a/src/pkg/event/aggregatedparser.go b/pkg/event/aggregatedparser.go similarity index 100% rename from src/pkg/event/aggregatedparser.go rename to pkg/event/aggregatedparser.go diff --git a/src/pkg/event/asgterminate/lifecycleaction/complete.go b/pkg/event/asgterminate/lifecycleaction/complete.go similarity index 100% rename from src/pkg/event/asgterminate/lifecycleaction/complete.go rename to pkg/event/asgterminate/lifecycleaction/complete.go diff --git a/src/pkg/event/asgterminate/v1/handler.go b/pkg/event/asgterminate/v1/handler.go similarity index 100% rename from src/pkg/event/asgterminate/v1/handler.go rename to pkg/event/asgterminate/v1/handler.go diff --git a/src/pkg/event/asgterminate/v1/parser.go b/pkg/event/asgterminate/v1/parser.go similarity index 100% rename from src/pkg/event/asgterminate/v1/parser.go rename to pkg/event/asgterminate/v1/parser.go diff --git a/src/pkg/event/asgterminate/v1/types.go b/pkg/event/asgterminate/v1/types.go similarity index 100% rename from src/pkg/event/asgterminate/v1/types.go rename to pkg/event/asgterminate/v1/types.go diff --git a/src/pkg/event/asgterminate/v1/unmarshal.go b/pkg/event/asgterminate/v1/unmarshal.go similarity index 100% rename from src/pkg/event/asgterminate/v1/unmarshal.go rename to pkg/event/asgterminate/v1/unmarshal.go diff --git a/src/pkg/event/asgterminate/v2/handler.go b/pkg/event/asgterminate/v2/handler.go similarity index 100% rename from src/pkg/event/asgterminate/v2/handler.go rename to pkg/event/asgterminate/v2/handler.go diff --git a/src/pkg/event/asgterminate/v2/parser.go b/pkg/event/asgterminate/v2/parser.go similarity index 100% rename from src/pkg/event/asgterminate/v2/parser.go rename to pkg/event/asgterminate/v2/parser.go diff --git a/src/pkg/event/asgterminate/v2/types.go b/pkg/event/asgterminate/v2/types.go similarity index 100% rename from src/pkg/event/asgterminate/v2/types.go rename to pkg/event/asgterminate/v2/types.go diff --git a/src/pkg/event/asgterminate/v2/unmarshal.go b/pkg/event/asgterminate/v2/unmarshal.go similarity index 100% rename from src/pkg/event/asgterminate/v2/unmarshal.go rename to pkg/event/asgterminate/v2/unmarshal.go diff --git a/src/pkg/event/metadata.go b/pkg/event/metadata.go similarity index 100% rename from src/pkg/event/metadata.go rename to pkg/event/metadata.go diff --git a/src/pkg/event/noop.go b/pkg/event/noop.go similarity index 100% rename from src/pkg/event/noop.go rename to pkg/event/noop.go diff --git a/src/pkg/event/rebalancerecommendation/v0/handler.go b/pkg/event/rebalancerecommendation/v0/handler.go similarity index 100% rename from src/pkg/event/rebalancerecommendation/v0/handler.go rename to pkg/event/rebalancerecommendation/v0/handler.go diff --git a/src/pkg/event/rebalancerecommendation/v0/parser.go b/pkg/event/rebalancerecommendation/v0/parser.go similarity index 100% rename from src/pkg/event/rebalancerecommendation/v0/parser.go rename to pkg/event/rebalancerecommendation/v0/parser.go diff --git a/src/pkg/event/rebalancerecommendation/v0/unmarshal.go b/pkg/event/rebalancerecommendation/v0/unmarshal.go similarity index 100% rename from src/pkg/event/rebalancerecommendation/v0/unmarshal.go rename to pkg/event/rebalancerecommendation/v0/unmarshal.go diff --git a/src/pkg/event/scheduledchange/v1/handler.go b/pkg/event/scheduledchange/v1/handler.go similarity index 100% rename from src/pkg/event/scheduledchange/v1/handler.go rename to pkg/event/scheduledchange/v1/handler.go diff --git a/src/pkg/event/scheduledchange/v1/parser.go b/pkg/event/scheduledchange/v1/parser.go similarity index 100% rename from src/pkg/event/scheduledchange/v1/parser.go rename to pkg/event/scheduledchange/v1/parser.go diff --git a/src/pkg/event/scheduledchange/v1/unmarshal.go b/pkg/event/scheduledchange/v1/unmarshal.go similarity index 100% rename from src/pkg/event/scheduledchange/v1/unmarshal.go rename to pkg/event/scheduledchange/v1/unmarshal.go diff --git a/src/pkg/event/spotinterruption/v1/handler.go b/pkg/event/spotinterruption/v1/handler.go similarity index 100% rename from src/pkg/event/spotinterruption/v1/handler.go rename to pkg/event/spotinterruption/v1/handler.go diff --git a/src/pkg/event/spotinterruption/v1/parser.go b/pkg/event/spotinterruption/v1/parser.go similarity index 100% rename from src/pkg/event/spotinterruption/v1/parser.go rename to pkg/event/spotinterruption/v1/parser.go diff --git a/src/pkg/event/spotinterruption/v1/unmarshal.go b/pkg/event/spotinterruption/v1/unmarshal.go similarity index 100% rename from src/pkg/event/spotinterruption/v1/unmarshal.go rename to pkg/event/spotinterruption/v1/unmarshal.go diff --git a/src/pkg/event/statechange/v1/handler.go b/pkg/event/statechange/v1/handler.go similarity index 100% rename from src/pkg/event/statechange/v1/handler.go rename to pkg/event/statechange/v1/handler.go diff --git a/src/pkg/event/statechange/v1/parser.go b/pkg/event/statechange/v1/parser.go similarity index 100% rename from src/pkg/event/statechange/v1/parser.go rename to pkg/event/statechange/v1/parser.go diff --git a/src/pkg/event/statechange/v1/unmarshal.go b/pkg/event/statechange/v1/unmarshal.go similarity index 100% rename from src/pkg/event/statechange/v1/unmarshal.go rename to pkg/event/statechange/v1/unmarshal.go diff --git a/src/pkg/logging/alias.go b/pkg/logging/alias.go similarity index 100% rename from src/pkg/logging/alias.go rename to pkg/logging/alias.go diff --git a/src/pkg/logging/sqs/deletemessageinput.go b/pkg/logging/sqs/deletemessageinput.go similarity index 100% rename from src/pkg/logging/sqs/deletemessageinput.go rename to pkg/logging/sqs/deletemessageinput.go diff --git a/src/pkg/logging/sqs/message.go b/pkg/logging/sqs/message.go similarity index 100% rename from src/pkg/logging/sqs/message.go rename to pkg/logging/sqs/message.go diff --git a/src/pkg/logging/sqs/receivemessagesinput.go b/pkg/logging/sqs/receivemessagesinput.go similarity index 100% rename from src/pkg/logging/sqs/receivemessagesinput.go rename to pkg/logging/sqs/receivemessagesinput.go diff --git a/src/pkg/logging/writer.go b/pkg/logging/writer.go similarity index 100% rename from src/pkg/logging/writer.go rename to pkg/logging/writer.go diff --git a/src/pkg/node/cordondrain/config.go b/pkg/node/cordondrain/config.go similarity index 100% rename from src/pkg/node/cordondrain/config.go rename to pkg/node/cordondrain/config.go diff --git a/src/pkg/node/cordondrain/kubectl/builder.go b/pkg/node/cordondrain/kubectl/builder.go similarity index 100% rename from src/pkg/node/cordondrain/kubectl/builder.go rename to pkg/node/cordondrain/kubectl/builder.go diff --git a/src/pkg/node/cordondrain/kubectl/cordondrainer.go b/pkg/node/cordondrain/kubectl/cordondrainer.go similarity index 100% rename from src/pkg/node/cordondrain/kubectl/cordondrainer.go rename to pkg/node/cordondrain/kubectl/cordondrainer.go diff --git a/src/pkg/node/cordondrain/kubectl/cordonfunc.go b/pkg/node/cordondrain/kubectl/cordonfunc.go similarity index 100% rename from src/pkg/node/cordondrain/kubectl/cordonfunc.go rename to pkg/node/cordondrain/kubectl/cordonfunc.go diff --git a/src/pkg/node/cordondrain/kubectl/drainfunc.go b/pkg/node/cordondrain/kubectl/drainfunc.go similarity index 100% rename from src/pkg/node/cordondrain/kubectl/drainfunc.go rename to pkg/node/cordondrain/kubectl/drainfunc.go diff --git a/src/pkg/node/getter.go b/pkg/node/getter.go similarity index 100% rename from src/pkg/node/getter.go rename to pkg/node/getter.go diff --git a/src/pkg/node/name/getter.go b/pkg/node/name/getter.go similarity index 100% rename from src/pkg/node/name/getter.go rename to pkg/node/name/getter.go diff --git a/src/pkg/sqsmessage/client.go b/pkg/sqsmessage/client.go similarity index 100% rename from src/pkg/sqsmessage/client.go rename to pkg/sqsmessage/client.go diff --git a/src/pkg/terminator/adapter/cordondrainbuilder.go b/pkg/terminator/adapter/cordondrainbuilder.go similarity index 100% rename from src/pkg/terminator/adapter/cordondrainbuilder.go rename to pkg/terminator/adapter/cordondrainbuilder.go diff --git a/src/pkg/terminator/adapter/getter.go b/pkg/terminator/adapter/getter.go similarity index 100% rename from src/pkg/terminator/adapter/getter.go rename to pkg/terminator/adapter/getter.go diff --git a/src/pkg/terminator/adapter/nodegetter.go b/pkg/terminator/adapter/nodegetter.go similarity index 100% rename from src/pkg/terminator/adapter/nodegetter.go rename to pkg/terminator/adapter/nodegetter.go diff --git a/src/pkg/terminator/adapter/parser.go b/pkg/terminator/adapter/parser.go similarity index 100% rename from src/pkg/terminator/adapter/parser.go rename to pkg/terminator/adapter/parser.go diff --git a/src/pkg/terminator/adapter/sqsclient.go b/pkg/terminator/adapter/sqsclient.go similarity index 100% rename from src/pkg/terminator/adapter/sqsclient.go rename to pkg/terminator/adapter/sqsclient.go diff --git a/src/pkg/terminator/adapter/webhookclient.go b/pkg/terminator/adapter/webhookclient.go similarity index 100% rename from src/pkg/terminator/adapter/webhookclient.go rename to pkg/terminator/adapter/webhookclient.go diff --git a/src/pkg/terminator/eventkind.go b/pkg/terminator/eventkind.go similarity index 100% rename from src/pkg/terminator/eventkind.go rename to pkg/terminator/eventkind.go diff --git a/src/pkg/terminator/reconciler.go b/pkg/terminator/reconciler.go similarity index 100% rename from src/pkg/terminator/reconciler.go rename to pkg/terminator/reconciler.go diff --git a/src/pkg/webhook/builder.go b/pkg/webhook/builder.go similarity index 100% rename from src/pkg/webhook/builder.go rename to pkg/webhook/builder.go diff --git a/src/pkg/webhook/client.go b/pkg/webhook/client.go similarity index 100% rename from src/pkg/webhook/client.go rename to pkg/webhook/client.go diff --git a/src/pkg/webhook/notification.go b/pkg/webhook/notification.go similarity index 100% rename from src/pkg/webhook/notification.go rename to pkg/webhook/notification.go diff --git a/src/pkg/webhook/request.go b/pkg/webhook/request.go similarity index 100% rename from src/pkg/webhook/request.go rename to pkg/webhook/request.go diff --git a/resources/dev-infrastructure.yaml b/resources/dev-infrastructure.yaml new file mode 100644 index 00000000..bf9ed402 --- /dev/null +++ b/resources/dev-infrastructure.yaml @@ -0,0 +1,40 @@ +AWSTemplateFormatVersion: "2010-09-09" + +Description: ECR Repositories for AWS Node Termination Handler Kubernetes controller and admissions webhook. + +Parameters: + ClusterName: + Description: EKS Cluster Name + Type: String + +Resources: + ControllerRepository: + Description: AWS ECR Repository where development builds of the AWS Node Termination Handler controller will be pushed. + Type: AWS::ECR::Repository + Properties: + RepositoryName: !Sub "nthv2/${ClusterName}/controller" + ImageTagMutability: MUTABLE + ImageScanningConfiguration: + ScanOnPush: false + + WebhookRepository: + Description: AWS ECR Repository where development builds of the AWS Node Termination Handler webhook handler will be pushed. + Type: AWS::ECR::Repository + Properties: + RepositoryName: !Sub "nthv2/${ClusterName}/webhook" + ImageTagMutability: MUTABLE + ImageScanningConfiguration: + ScanOnPush: false + +Outputs: + ControllerRepositoryName: + Description: Name of the controller's ECR image repository. + Value: !Ref ControllerRepository + + RepositoryBaseURI: + Description: Base URI for the controller and webhook image repositories. + Value: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/nthv2/${ClusterName}" + + WebhookRepositoryName: + Description: Name of the controller's ECR image repository. + Value: !Ref WebhookRepository diff --git a/src/resources/eks-cluster.yaml.tmpl b/resources/eks-cluster.yaml.tmpl similarity index 100% rename from src/resources/eks-cluster.yaml.tmpl rename to resources/eks-cluster.yaml.tmpl diff --git a/resources/infrastructure.yaml b/resources/infrastructure.yaml new file mode 100644 index 00000000..b6c647eb --- /dev/null +++ b/resources/infrastructure.yaml @@ -0,0 +1,34 @@ +AWSTemplateFormatVersion: "2010-09-09" + +Description: IAM Managed Policy for AWS Node Termination Handler Kubernetes controller. + +Parameters: + ClusterName: + Description: EKS Cluster Name + Type: String + +Resources: + ServiceAccountPolicy: + Description: > + This policy should be attached to the Kubernetes Service Account that will be used + by the AWS Node Termination Handler controller process to interact with AWS resources. + Type: AWS::IAM::ManagedPolicy + Properties: + ManagedPolicyName: !Sub "${ClusterName}-serviceaccount" + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Action: + - autoscaling:CompleteLifecycleAction + - autoscaling:DescribeAutoScalingInstances + - autoscaling:DescribeTags + - ec2:DescribeInstances + - sqs:DeleteMessage + - sqs:ReceiveMessage + Resource: "*" + +Outputs: + ServiceAccountPolicyARN: + Description: ARN of the IAM Policy created for the Kubernetes Service Account. + Value: !Ref ServiceAccountPolicy diff --git a/resources/queue-infrastructure.yaml b/resources/queue-infrastructure.yaml new file mode 100644 index 00000000..77607a6f --- /dev/null +++ b/resources/queue-infrastructure.yaml @@ -0,0 +1,135 @@ +AWSTemplateFormatVersion: "2010-09-09" + +Description: SQS Queue and EventBridge Rules for messages handled by AWS Node Termination Handler. + +Parameters: + ClusterName: + Description: EKS Cluster Name + Type: String + + MessageRetentionPeriod: + Description: The number of seconds that SQS will retain a message. + Type: Number + MinValue: 60 + MaxValue: 1209600 + Default: 300 + + QueueName: + Description: Name for new queue + Type: String + +Resources: + Queue: + Description: Queue for messages from EC2 Auto Scaling. + Type: AWS::SQS::Queue + Properties: + QueueName: !Ref QueueName + MessageRetentionPeriod: !Ref MessageRetentionPeriod + Tags: + - Key: "nth:cluster-name" + Value: !Ref ClusterName + + AutoScalingTerminateRule: + Type: AWS::Events::Rule + Properties: + Name: !Sub "nth_${ClusterName}_${QueueName}_auto-scaling-terminate" + Description: !Sub "Route instance-terminate lifecycle actions from EC2 Auto Scaling to SQS Queue, ${QueueName}." + EventPattern: + source: + - aws.autoscaling + detail-type: + - EC2 Instance-terminate Lifecycle Action + version: + - "1" + - "2" + detail: + LifecycleTransition: + - "autoscaling:EC2_INSTANCE_TERMINATING" + State: ENABLED + Targets: + - Id: !GetAtt Queue.QueueName + Arn: !GetAtt Queue.Arn + + RebalanceRecommendationRule: + Type: AWS::Events::Rule + Properties: + Name: !Sub "nth_${ClusterName}_${QueueName}_rebalance-recommendation" + Description: !Sub "Route rebalance recommendations from EC2 to SQS Queue, ${QueueName}." + EventPattern: + source: + - aws.ec2 + detail-type: + - EC2 Instance Rebalance Recommendation + version: + - "0" + State: ENABLED + Targets: + - Id: !GetAtt Queue.QueueName + Arn: !GetAtt Queue.Arn + + ScheduledChangeRule: + Type: AWS::Events::Rule + Properties: + Name: !Sub "nth_${ClusterName}_${QueueName}_scheduled-change" + Description: !Sub "Route scheduled change health events from AWS Health to SQS Queue, ${QueueName}." + EventPattern: + source: + - aws.health + detail-type: + - AWS Health Event + version: + - "1" + detail: + source: + - EC2 + eventTypeCategory: + - scheduledChange + State: ENABLED + Targets: + - Id: !GetAtt Queue.QueueName + Arn: !GetAtt Queue.Arn + + SpotInterruptionRule: + Type: AWS::Events::Rule + Properties: + Name: !Sub "nth_${ClusterName}_${QueueName}_spot-interruption" + Description: !Sub "Route spot interruption notices from EC2 to SQS Queue, ${QueueName}." + EventPattern: + source: + - aws.ec2 + detail-type: + - EC2 Spot Instance Interruption Warning + version: + - "1" + State: ENABLED + Targets: + - Id: !GetAtt Queue.QueueName + Arn: !GetAtt Queue.Arn + + StateChangeRule: + Type: AWS::Events::Rule + Properties: + Name: !Sub "nth_${ClusterName}_${QueueName}_state-change" + Description: !Sub "Route state change notifications from EC2 to SQS Queue, ${QueueName}." + EventPattern: + source: + - aws.ec2 + detail-type: + - EC2 Instance State-change Notification + version: + - "1" + detail: + state: + - stopping + - stopped + - shutting-down + - terminated + State: ENABLED + Targets: + - Id: !GetAtt Queue.QueueName + Arn: !GetAtt Queue.Arn + +Outputs: + QueueURL: + Description: URL of SQS Queue. + Value: !Ref Queue diff --git a/resources/terminator.yaml.tmpl b/resources/terminator.yaml.tmpl new file mode 100644 index 00000000..ef674775 --- /dev/null +++ b/resources/terminator.yaml.tmpl @@ -0,0 +1,33 @@ +apiVersion: node.k8s.aws/v1alpha1 +kind: Terminator +metadata: + name: ${TERMINATOR_NAME} + +spec: + sqs: + queueURL: ${QUEUE_URL} + + #matchLabels: + # myLabel: foo + + #events: + # autoScalingTermination: CordonAndDrain + # rebalanceRecommendation: CordonAndDrain + # scheduledChange: CordonAndDrain + # spotInterruption: CordonAndDrain + # stateChange: CordonAndDrain + + #drain: + # force: true + # gracePeriodSeconds: -1 + # ignoreAllDaemonSets: true + # deleteEmptyDirData: true + # timeoutSeconds: 120 + + #webhook: + # url: http://example.com/my-webhook + # proxyURL: https://proxy.example.com + # headers: + # - name: X-My-Custom-Header + # value: foo + # template: 'Kind: {{ .Kind }}, Node: {{ .NodeName }}, EventID: {{ .EventID }}' diff --git a/scripts/clear-image-repo.sh b/scripts/clear-image-repo.sh new file mode 100755 index 00000000..0d70e4e4 --- /dev/null +++ b/scripts/clear-image-repo.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +usage=$(cat << EOM +usage: $(basename "$0") -h | REPO_NAME + + Delete all images in an ECR repository. + + Options: + -h Print usage message then exit. + + Arguments: + REPO_NAME Image repository name. + +EOM +) + +while getopts "h" opt; do + case $opt in + h ) echo "${usage}" + exit 0 + ;; + \? ) echo "${usage}" 1>&2 + exit 1 + ;; + esac +done + +repo_name="$1" + +if [[ -z "${repo_name}" ]]; then + echo "error: missing repository name" 1>&2 + echo 1>&2 + echo "${usage}" 1>&2 + exit 1 +fi + + +aws ecr batch-delete-image \ + --repository-name "${repo_name}" \ + --image-ids "$(aws ecr list-images --repository-name "${repo_name}" --query imageIds --output json)" diff --git a/src/scripts/docker-login-ecr.sh b/scripts/docker-login-ecr.sh similarity index 100% rename from src/scripts/docker-login-ecr.sh rename to scripts/docker-login-ecr.sh diff --git a/src/scripts/download-kubebuilder-assets.sh b/scripts/download-kubebuilder-assets.sh similarity index 100% rename from src/scripts/download-kubebuilder-assets.sh rename to scripts/download-kubebuilder-assets.sh diff --git a/scripts/get-cfn-stack-output.sh b/scripts/get-cfn-stack-output.sh new file mode 100755 index 00000000..eb161a50 --- /dev/null +++ b/scripts/get-cfn-stack-output.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +usage=$(cat << EOM +usage: $(basename "$0") -h | STACK_NAME OUTPUT_NAME + + Get the specified output value from a CloudFormation stack. + + Options: + -h Print usage message then exit. + + Arguments: + STACK_NAME Name of Cloud Formation stack. + OUTPUT_NAME Name of output in Cloud Formation stack. + +EOM +) + +while getopts "h" opt; do + case $opt in + h ) echo "${usage}" + exit 0 + ;; + \? ) echo "${usage}" 1>&2 + exit 1 + ;; + esac +done + +stack_name="$1" + +if [[ -z "${stack_name}" ]]; then + echo "error: missing stack name" 1>&2 + echo 1>&2 + echo "${usage}" 1>&2 + exit 1 +fi + +output_name="$2" + +if [[ -z "${output_name}" ]]; then + echo "error: missing output name" 1>&2 + echo 1>&2 + echo "${usage}" 1>&2 + exit 1 +fi + +aws cloudformation describe-stacks \ + --stack-name "${stack_name}" \ + --query "Stacks[0].Outputs[?OutputKey=='${output_name}'].OutputValue | [0]" \ + --output text diff --git a/src/.gitignore b/src/.gitignore deleted file mode 100644 index 79f1eb0d..00000000 --- a/src/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ - -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib -bin -testbin/* - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Kubernetes Generated files - skip generated files, except for vendored files - -!vendor/**/zz_generated.* - -# editor and IDE paraphernalia -.idea -*.swp -*.swo -*~ -cmd/**/kodata/ - diff --git a/src/charts/aws-node-termination-handler-2/README.md b/src/charts/aws-node-termination-handler-2/README.md deleted file mode 100644 index 29df6157..00000000 --- a/src/charts/aws-node-termination-handler-2/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# AWS Node Termination Handler - -AWS Node Termination Handler Helm chart for Kubernetes. For more information on this project see the project repo at [github.com/aws/aws-node-termination-handler](https://github.com/aws/aws-node-termination-handler). - -## Prerequisites - -- _Kubernetes_ >= 1.16 - -## Installing the Chart - -Before you can install the chart you will need to add the `aws` repo to [Helm](https://helm.sh/). - -```shell -helm repo add eks https://aws.github.io/eks-charts/ -``` diff --git a/src/charts/aws-node-termination-handler-2/values.yaml b/src/charts/aws-node-termination-handler-2/values.yaml deleted file mode 100644 index 9923fd61..00000000 --- a/src/charts/aws-node-termination-handler-2/values.yaml +++ /dev/null @@ -1,157 +0,0 @@ -# Override chart name. -nameOverride: "" - -# Override compute chart full name. -fullnameOverride: "" - -# Labels to add to Kubernetes objects created by Helm deployment. -labels: {} - -# Annotations to add to Kubernetes objects created by Helm deployment. -annotations: {} - -terminator: - defaults: - drain: - force: true - gracePeriodSeconds: -1 - ignoreAllDaemonSets: true - deleteEmptyDirData: true - timeoutSeconds: 120 - webhook: - headers: - - name: Content-Type - value: application/json - template: '{"text":"[NTH][Instance Interruption] EventID: {{ .EventID }} - Kind: {{ .Kind }} - Instance: {{ .InstanceID }} - Node: {{ .NodeName }} - Start Time: {{ .StartTime }}"}' - -aws: - # AWS region to use in API calls. - region: "" - -# Global logging configuration. -# See https://github.com/uber-go/zap/blob/2314926ec34c23ee21f3dd4399438469668f8097/config.go#L58-L94 -# for descriptions of each option. -logging: - level: info - development: false - disableStacktrace: true - disableCaller: true - sampling: - initial: 100 - thereafter: 100 - outputPaths: - - stdout - errorOutputPaths: - - stderr - encoding: console - encoderConfig: - timeKey: time - levelKey: level - nameKey: logger - callerKey: caller - messageKey: message - stacktraceKey: stacktrace - levelEncoder: capital - timeEncoder: iso8601 - -pod: - # Number of aws-node-termination-handler controller instance pods. - replicas: 1 - - # Update strategy for pods. - updateStrategy: - type: Recreate - - # Labels to add to pods. - labels: {} - - # Annotations to add to pods. - annotations: {} - - # Security group configuration for pods. - securityContext: - fsGroup: 1000 - - # Priority class for the pods. - priorityClassName: "system-cluster-critical" - - # Bind the pod to the host network. - hostNetwork: false - - # Node labels to match when scheduling pods. - nodeSelector: - kubernetes.io/os: linux - -# Secret for accessing image. -imagePullSecrets: [] - -# Policy on when to pull image. -imagePullPolicy: IfNotPresent - -rbac: - # Create the RBAC objects. May fail if RBAC objects already exist. - create: true - -serviceAccount: - - # Create the service account. May fail if service account already exists. - create: true - - # Name of service account. If empty then a name will be generated. - name: "" - - # Annotations to add to the service account. - annotations: {} - -controller: - # Image to deploy. - image: "public.ecr.aws/aws-node-termination-handler:v2.0.0-0.1" - - # Additional security context configuration for the controller pod. - securityContext: {} - - # Environment variables. - env: [] - # Example: - # - name: AWS_REGION - # . value: eu-west-1 - - # Resources for the controller pod. - resources: - requests: - cpu: 1 - memory: 1Gi - limits: - cpu: 1 - memory: 1Gi - - # Minimum event level to log; "" to use global logLevel. - logLevel: "" - -webhook: - # Image to deploy. - image: "public.ecr.aws/aws-node-termination-handler:v2.0.0-0.1" - - # Listen on port. - port: 8443 - - # Additional security context configuration for the controller pod. - securityContext: {} - - # Environment variables. - env: [] - # Example: - # - name: AWS_REGION - # . value: eu-west-1 - - # Resources for the controller pod. - resources: - requests: - cpu: 100m - memory: 50Mi - limits: - cpu: 100m - memory: 50Mi - - # Minimum event level to log; "" to use global logLevel. - logLevel: "" diff --git a/src/resources/controller-iam-role.yaml b/src/resources/controller-iam-role.yaml deleted file mode 100644 index ee89e4f2..00000000 --- a/src/resources/controller-iam-role.yaml +++ /dev/null @@ -1,23 +0,0 @@ -AWSTemplateFormatVersion: "2010-09-09" -Description: Resources used by AWS Node Termination Handler v2 -Parameters: - ClusterName: - Type: String - Description: "EKS cluster name" -Resources: - Nthv2ControllerPolicy: - Type: AWS::IAM::ManagedPolicy - Properties: - ManagedPolicyName: !Sub "Nthv2ControllerPolicy-${ClusterName}" - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Resource: "*" - Action: - - autoscaling:CompleteLifecycleAction - - autoscaling:DescribeAutoScalingInstances - - autoscaling:DescribeTags - - ec2:DescribeInstances - - sqs:DeleteMessage - - sqs:ReceiveMessage diff --git a/src/test/app_integ_suite_test.go b/test/app_integ_suite_test.go similarity index 100% rename from src/test/app_integ_suite_test.go rename to test/app_integ_suite_test.go diff --git a/src/test/asgclient.go b/test/asgclient.go similarity index 100% rename from src/test/asgclient.go rename to test/asgclient.go diff --git a/src/test/ec2client.go b/test/ec2client.go similarity index 100% rename from src/test/ec2client.go rename to test/ec2client.go diff --git a/src/test/kubeclient.go b/test/kubeclient.go similarity index 100% rename from src/test/kubeclient.go rename to test/kubeclient.go diff --git a/src/test/reconciliation_test.go b/test/reconciliation_test.go similarity index 100% rename from src/test/reconciliation_test.go rename to test/reconciliation_test.go diff --git a/src/test/sqsclient.go b/test/sqsclient.go similarity index 100% rename from src/test/sqsclient.go rename to test/sqsclient.go